Java拾贝第十五天——集合之Iterator迭代器

发布时间 2023-11-03 14:13:47作者: ocraft

虽然for each循环可以遍历集合输出,但书上提及了一个观点。

只要碰到了集合输出的操作,就一定要使用Iterator(迭代器)接口

实际上编译器把for each循环通过Iterator改写为了普通的for循环

上述的观点在本文最后一部分会提及。

Iterator

Iterator是专门的迭代输出接口,所谓迭代就是将元素一个个进行判断,判断是否有内容,如果有则把内容取出:
image

Iterator接口定义如下:

public interface Iterator<E>

也使用了泛型,当然迭代器的泛型需要和集合指定的泛型相同。

Iterator内部定义了三个方法:

方法 类型 描述
boolean hasNext() 普通方法 判断是否有下一个值
E next() 普通方法 取出当前元素
void remove() 普通方法 移除当前元素

接口中的方法默认公开抽象 public abstract

如何实例化Iterator()

在Collection接口中定义了Iterator()方法为某集合实例化一个迭代器。

既然Collection接口中存在了此方法,那么List接口和Set接口的实现类也可也使用该方法调用迭代器。

boolean hasNext() 和 E next()

判断是否有下一个值 和 取出当前元素
栗子:

    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("你好");
        list.add("嗨咯");
        list.add("hello");
        list.add("hi");

        Iterator<String> iterator = list.iterator();//返回一个迭代器实例
        while (iterator.hasNext()){
            System.out.println(iterator.next());//输出当前元素
        }
    }

程序运行结果:

你好
嗨咯
hello
hi

void remove()

删除当前元素
栗子:

    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("你好");
        list.add("嗨咯");
        list.add("hello");
        list.add("hi");

        Iterator<String> iterator = list.iterator();//返回一个迭代器实例
        while (iterator.hasNext()){
            String temp =iterator.next();//拿一个变量接收当前对象

            if (temp.equals("hi")){
                iterator.remove();//删除hi
            }else {
                System.out.println(temp);
            }
        }
    }

程序运行结果:

你好
嗨咯
hello

注意
此时调用的是迭代器里的remove()方法。

如果在迭代器输出时用集合对象remove()方法会导致异常:

栗子:

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("你好");
        list.add("嗨咯");
        list.add("hello");
        list.add("hi");

        Iterator<String> iterator = list.iterator();//返回一个迭代器实例
        while (iterator.hasNext()) {
            String temp = iterator.next();//拿一个变量接收当前对象
            if (temp.equals("hi")) {
                list.remove(temp);
            } else {
                System.out.println(temp);
            }
        }
    }

程序运行结果:

你好
嗨咯
hello
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
	at java.util.ArrayList$Itr.next(ArrayList.java:861)
	at moudle2.Test15.main(Test15.java:17)

Process finished with exit code 1

因为此时集合本身被破坏了,迭代出现错误。

为什么一定要使用Iterator?

因为使用for循环进行遍历集合需要知道集合的内部构造。

如果遍历有序集合,直接使用下标即可。
如果遍历无序集合,无法像有序集合一样使用下标进行遍历。

所以使用迭代器的好处就是不用知道集合的内部构造。
一种方式针对多种集合,万金油的遍历方式。