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