Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

8.8. Iterator

Iterator接口包含四个方法:hasNext,next,remove,forEachRemaining

8.8.1. List 迭代

		
package cn.netkiller.test;

import java.util.Iterator;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        Test test = new Test();

//        ArrayList<String> arrayList = new ArrayList<String>();

        List<String> list = List.of("Neo", "Tom", "Jerry");

        System.out.printf("%s for %s\n", "=".repeat(10), "=".repeat(10));
        for (String name : list) {
            System.out.println(name);
        }
        System.out.printf("%s forEach %s\n", "=".repeat(10), "=".repeat(10));
        list.forEach(obj -> {
            System.out.println(obj);
        });


        Iterator<String> iterator = list.iterator();
        
        System.out.printf("%s while %s\n", "=".repeat(10), "=".repeat(10));
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        System.out.printf("%s forEachRemaining %s\n", "=".repeat(10), "=".repeat(10));
        iterator.forEachRemaining(System.out::println);

    }
}		
		
			

8.8.2. 处理剩余结果

			
iterator.forEachRemaining(System.out::println);
			
			

8.8.3. Map 迭代

			
package cn.netkiller.test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Test {

    public static void main(String[] args) {
        System.out.printf("%s Map<Integer, String> %s\n", "=".repeat(10), "=".repeat(10));
        Map<Integer, String> map = new HashMap<Integer, String>();
        for (int i = 0; i < 10; i++) {
            map.put(i, "map" + i);
        }
        Iterator iterMap = map.entrySet().iterator();
        while (iterMap.hasNext()) {
            Map.Entry strMap = (Map.Entry) iterMap.next();
            System.out.println("key: " + strMap.getKey() + ", value: " + strMap.getValue());
        }
    }
}			
			
			

8.8.4. Iterator 与 List 的区别

List 加载后放入内存,可以可以反复使用,Iterator 一旦调用 next() 就会从内存中清除,无法再次引用。

			
package cn.netkiller.test;

import java.util.Iterator;
import java.util.List;

public class Test {

    public static void main(String[] args) {

        List<String> list = List.of("Neo", "Tom", "Jerry");

        System.out.printf("%s List<String> %s\n", "=".repeat(10), "=".repeat(10));
        list.forEach(System.out::println);

        Iterator<String> iterator = list.iterator();

        System.out.printf("%s next() %s\n", "=".repeat(10), "=".repeat(10));
        String name = iterator.next();
        System.out.println(name);

        System.out.printf("%s forEachRemaining() %s\n", "=".repeat(10), "=".repeat(10));
        iterator.forEachRemaining(System.out::println);

        System.out.printf("%s while hasNext() %s\n", "=".repeat(10), "=".repeat(10));
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

    }
}
			
			

输出结果

			
========== List<String> ==========
Neo
Tom
Jerry
========== next() ==========
Neo
========== forEachRemaining() ==========
Tom
Jerry
========== while hasNext() ==========
			
			

8.8.5. remove() 删除操作

			
package cn.netkiller.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>(List.of("Neo", "Tom", "Jerry"));

        System.out.printf("%s List<String> %s\n", "=".repeat(10), "=".repeat(10));
        list.forEach(System.out::println);
        Iterator<String> iterator = list.iterator();

        System.out.printf("%s remove() %s\n", "=".repeat(10), "=".repeat(10));
        while (iterator.hasNext()) {
            String name = iterator.next();

            if (name.equals("Tom")) {
                iterator.remove();
            } else {
                System.out.println(name);
            }

        }

    }
}			
			
			

UnsupportedOperationException 异常

			
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
	at java.base/java.util.ImmutableCollections$ListItr.remove(ImmutableCollections.java:387)
	at cn.netkiller.test.Test.main(Test.java:36)			
			
			

List.of 跟 Arrays.asList 不支持 remove() 操作,会抛出 UnsupportedOperationException 异常。

			
List<String> list = List.of("Neo", "Tom", "Jerry");
List<String> list = Arrays.asList("Neo", "Tom", "Jerry");
			
			

8.8.6. Iterable 转 List

			
	Iterable<Entity> iterable = repository.findAll();
	List<Entity> list = new ArrayList<>();
	iterable.forEach(single->{list.add(single);});
 
  	List<String> result = new ArrayList<String>();
    iterable.forEach(result::add);
 
    List<String> result = new ArrayList<String>();
    for (String str : iterable) {
        result.add(str);
    } 			
    
    List<String> result = new ArrayList<String>();
    while (iterator.hasNext()) {
        result.add(iterator.next());
    }
    
	List<String> result = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
	List<String> result = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false).collect(Collectors.toList());

    List<String> result = new ArrayList<String>();
    iterator.forEachRemaining(result::add);
    
			
			

8.8.7. ListIterator

ListIterator 可以实现添加/删除和向前/向后访问数据

Iterator 可以用于 List / Set / Vector / Map 数据结构,ListIterator 只能用于 List

		
package cn.netkiller.test;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class Test {

    public static void main(String[] args) {
        Test test = new Test();
        List<String> arrayList = new ArrayList<String>();
        List<String> linkedList = new LinkedList<String>();

        linkedList.add("Neo");
        linkedList.add("Tom");
        linkedList.add("Jerry");
        ListIterator<String> listIterator = linkedList.listIterator();
        String first = listIterator.next();

        System.out.printf("%s List<String> %s\n", "=".repeat(10), "=".repeat(10));
        System.out.println("first:" + first);

        listIterator.remove();

        System.out.printf("%s forEachRemaining %s\n", "=".repeat(10), "=".repeat(10));
        listIterator.add("Netkiller");
        listIterator.forEachRemaining(System.out::println);

        arrayList.add("Netkiller Linux 手札");
        arrayList.add("Netkiller Java 手札");
        arrayList.add("Netkiller Sprint 手札");

        listIterator = arrayList.listIterator();
        System.out.printf("%s next() %s\n", "=".repeat(10), "=".repeat(10));
        while (listIterator.hasNext()) {
            System.out.println(listIterator.next());
        }

        listIterator.add("Netkiller MySQL 手札");

        System.out.printf("%s previous() %s\n", "=".repeat(10), "=".repeat(10));
        while (listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }
    }
}		
		
			
		
String next = listIterator.next();
if( "Neo".equals(next)) {
    listIterator.set("Netkiller");
}		
		
			
		
List<String> items = new ArrayList<String>();
String nextWithIndex = items.get(listIterator.nextIndex());
String previousWithIndex = items.get(listIterator.previousIndex());		
		
			

8.8.8. Iterable

在 Java 中,Iterable接口是所有可迭代集合(如List、Set等)的父接口,其核心方法iterator()返回一个Iterator对象,用于遍历集合元素。

			
Iterable<String> iterable = Arrays.asList("a", "b", "c");

// for-each循环直接遍历元素
for (String element : iterable) {
    System.out.println(element); // 输出:a、b、c
}
			
			
			
Iterable<Integer> numbers = Arrays.asList(1, 2, 3, 4);
Iterator<Integer> iterator = numbers.iterator();

// 循环判断是否有下一个元素
while (iterator.hasNext()) {
    Integer num = iterator.next(); // 获取下一个元素
    System.out.println(num);
    
    // 示例:删除偶数(仅支持可修改的集合,如ArrayList,不可修改集合会抛异常)
    if (num % 2 == 0) {
        iterator.remove(); // 必须在next()之后调用,否则报错
    }
}			
			
			

对于支持流式操作的Iterable(如集合类),可通过stream()或parallelStream()转换为流,结合 Lambda 表达式实现函数式遍历:

			
Iterable<String> words = Arrays.asList("apple", "banana", "cherry");

// 转换为流并遍历
words.forEach(word -> System.out.println(word.toUpperCase())); // 输出大写字母

// 更复杂的流操作(过滤、映射等)
((Collection<String>) words).stream() // 注意:需强转为Collection才能调用stream()
    .filter(word -> word.length() > 5)
    .forEach(System.out::println); // 输出:banana、cherry			
			
			

遍历自定义 Iterable 对象,若你自定义了实现Iterable接口的类,只需重写iterator()方法,即可使用上述所有遍历方式:

			
public class MyIterable implements Iterable<String> {
    private String[] data = {"x", "y", "z"};

    @Override
    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int index = 0;

            @Override
            public boolean hasNext() {
                return index < data.length;
            }

            @Override
            public String next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                return data[index++];
            }
        };
    }

    // 测试遍历
    public static void main(String[] args) {
        MyIterable myIterable = new MyIterable();
        for (String s : myIterable) {
            System.out.println(s); // 输出:x、y、z
        }
    }
}