Java迭代器 与 for循环的区别

Java迭代器 与 for循环的区别

 

 

1、Iterator接口:

Iterator接口包含三个主要的方法:hasNext,next,remove。

public interface Iterator<E> {
    /**
     * 是否存在下一个元素
     * @return
     */
    boolean hasNext();

    /**
     * 返回下一个元素
     * @return
     */
    E next();

    /**
     * 删除元素,需要具体的子类去实现,默认不支持删除操作
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

 

2、测试

2.1、集合结构只要发生改变,迭代器必须重新获取。否则会出现异常;java.util.ConcurrentModificationException
出异常根本原因是:集合中元素删除了,没有更新迭代器(迭代器不知道集合变化了)。
public static void main(String[] args) {
        // 创建集合
        Collection c = new ArrayList();
        Iterator it = c.iterator();

        // 添加元素
        c.add(1);

        // 重新获取迭代器
        // it = c.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }
    }

 

2.2、必须获取到下一个元素后(调用next()方法后), 才能调用remove方法,否则会抛出: java.lang.IllegalStateException。

直接通过集合的remove()方法去删除元素,没有通知迭代器。(导致迭代器的快照和原集合状态不同。)会导致异常:java.util.ConcurrentModificationException。
public static void main(String[] args) {
        ArrayList c2 = new ArrayList();
        c2.add("abc");
        c2.add("def");
        c2.add("xyz");

        Iterator it2 = c2.iterator();
        System.out.println(c2.size());
        while (it2.hasNext()) {
            //必须获取到下一个元素后, 才能调用remove方法,否则会抛出: java.lang.IllegalStateException
            Object o = it2.next();
            // 直接通过集合去删除元素,没有通知迭代器。(导致迭代器的快照和原集合状态不同。)会导致异常:java.util.ConcurrentModificationException
//            c2.remove(o);
            // 迭代器去删除时,会自动更新迭代器,并且更新集合(删除集合中的元素)。
//            删除的一定是迭代器指向的当前元素。
            it2.remove();
            System.out.println(c2.size());
        }
    }

 

3、总结

迭代器和for循环的效率比较(RandomAccess接口的作用):

  • for循环调用get()方法,是随机访问,比如:若使用ArrayList,对随机访问比较快,因此适合用for循环较快;
  • iterator调用next()方法,是顺序访问,比如:若使用LinkedList,对顺序访问比较快,因此适合用iterator迭代访问;

从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素。 而Iterator 适合访问链式结构,因为迭代器是通过next()和Pre()来定位的。可以访问没有顺序的集合.

集合元素的remove

  1. 当集合的结构发生改变时,迭代器必须重新获取,如果还是用以前老的迭代器,会出现 异常:java.util.ConcurrentModificationException
  2. 在迭代元素的过程当中,一定要使用迭代器Iterator的remove方法,删除元素, 不要使用集合自带的remove方法删除元素。