迭代(iterate):简单来说, 它就是一个循环。 集合框架中的Iterator接口定义了迭代器的功能, 迭代器的用途是遍历集合(容器) 中的所有元素。
1. Iterator接口
public interface Iterator<E> {
    boolean hasNext();
    
    E next();
    
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}
import java.util.ArrayList;
import java.util.Iterator;
class Test {
    private ArrayList<String> names;
    Test() {
        names = new ArrayList<String>();
        names.add("zhang");
        names.add("wang");
        names.add("li");
        names.add("zhao");
    }
    public void print() {
        // 获取迭代器
        Iterator<String> it = names.iterator();
        // 输出集合中的第一个元素
        System.out.println(it.next());
    }
    public void show() {
        // 输出所有元素
        Iterator<String> it = names.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
    public void remove() {
        Iterator<String> it = names.iterator();
        while(it.hasNext()) {
            if(it.next().equals("zhang"))
                it.remove();
        }
        System.out.println(names);
    }
}
public class App {
    public static void main(String[] args) {
            new Test().print();
            System.out.println("-----------");
            new Test().show();
            System.out.println("-----------");
            new Test().remove();
    }
}
注意:Java 迭代器是一种单向遍历机制,即只能从前往后遍历集合中的元素,不能往回遍历。同时,在使用迭代器遍历集合时,不能直接修改集合中的元素,而是需要使用迭代器的 remove() 方法来删除当前元素。
2. 迭代器与for…each循序
Java 5 引入了 for...each 循环, 它天生就是为迭代器而设计的, 只要集合类实现了Iterable接口, 就可以使用 for...each" 循环, 而Collection这一系的集合类都实现了Iterable接口, 所以都可以应用for...each 循环。这个东西呢在C++中叫区间for循环,当然,在Java中也可以这样称谓它。
public class App {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("111");
        list.add("222");
        list.add("333");
        list.add("444");
		// for...each循环
        for(String str: list) {
            System.out.println(str);
        }
    }
}
当然了,如果我们自己写的类实现了Iterable接口, 那么它也可以应用“for…each”循环。
public interface Iterable<T> {
    Iterator<T> iterator();
    
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}
class MyList implements Iterable<Integer> {
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            private int[] arr = new int[] { 2, 4 , 5, 232, 121 };
            private int pos = 0;
            @Override
            public boolean hasNext() {
                return pos < arr.length;
            }
            @Override
            public Integer next() {
                return arr[pos++];
            }
        };
    }
}
public class App {
    public static void main(String[] args) {
        MyList list = new MyList();
        for(Integer num: list) {
            System.out.print(num + " ");
        }
    }
}
3. forEach()方法
Java8为Iterable接口新增了forEach()方法默认方法。可以在实现Iterable接口的对象上调用forEach()方法。
public class App {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("111");
        list.add("222");
        list.add("333");
        list.add("444");
        list.forEach(elem -> System.out.print(elem + " ")); // 使用lambda表达式传参
        System.out.println("");
        list.forEach(System.out::println);                  // 使用方法引用传参
    }
}
4. ListIterator接口
实现Iterator接口的迭代器只能朝着一个方向遍历集合中的元素, 在大多数情况下, 这已经能满足我们的需求了, 但在有些情况下, 我们也希望能够按任一方向遍历集合, 并可以在迭代期间修改集合, 为此, 集合框架中给出了ListIterator接口。
public class App {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.addAll(Arrays.asList(1, 2, 3, 4, 5));
        ListIterator<Integer> lsIt = list.listIterator();
        System.out.println("正向遍历:> ");
        while(lsIt.hasNext()) {
            System.out.print(lsIt.next() + " ");
        }
        System.out.println(lsIt.nextIndex());       // 5
        System.out.println("\n------------------");
        System.out.println("反向遍历:> ");
        while(lsIt.hasPrevious()) {
            System.out.print(lsIt.previous() + " ");
        }
        System.out.println("\n------------------");
        /*
        * nextIndex:>       返回后续调用next()方法所返回的元素的索引位置; 如果迭代器在列表结尾, 则返回列表的大小;
        * previousIndex:>   返回... previous() ...; 如果迭代器在列表开始, 则返回-1;
        * */
        System.out.println("迭代器索引位置:> ");
        System.out.println(lsIt.nextIndex());       // 0
        System.out.println(lsIt.previousIndex());   // -1
        while(lsIt.hasNext()) {
            lsIt.next();
        }
        System.out.println("索引位置:> ");
        System.out.println(lsIt.nextIndex());       // 5
    }
}




















