另外补充:
获取iterator 后,如果增加或删除了元素,要重写获取iterator~
原因是,获取iterator时,初始化iterator会记住对应集合的元素个数,之后增加或删除了集合中的元素,那么集合送元素个数和 iterator中记录的个数就不一致了,会报错(报的错误和下文中相同,因为本质上问题根源是一样的)
原文地址:
1.使用 for 循环
1 Listlist = new ArrayList<>(); 2 list.add("1"); 3 list.add("2"); 4 list.add("3"); 5 for (int i = 0; i < list.size(); i++) { 6 System.out.println(list.size()); 7 if ("1".equals(list.get(i))){ 8 list.add("4"); 9 list.remove("1");10 }11 }
1 Listlist = new ArrayList<>(); 2 list.add("1"); 3 list.add("2"); 4 list.add("3"); 5 for (String s : list){ 6 if ("1".equals(s)){ 7 list.add("4"); 8 list.remove("1"); 9 }10 }
1 Listlist = new ArrayList<>(); 2 list.add("1"); 3 list.add("2"); 4 list.add("3"); 5 Iterator iterator = list.iterator(); 6 while (iterator.hasNext()) { 7 if ("1".equals(iterator.next())) { 8 iterator.remove(); 9 list.add("4");10 list.remove("1");11 }12 }
1 private class Itr implements Iterator{2 ...3 }
1 public Iteratoriterator() {2 return new Itr();3 }
所以在调用集合的iterator方法之后实际上返回了一个内部类的实例。
我们看一下Itr这个类的next()方法是如何实现的:1 public E next() { 2 checkForComodification(); 3 try { 4 int i = cursor; 5 E next = get(i); 6 lastRet = i; 7 cursor = i + 1; 8 return next; 9 } catch (IndexOutOfBoundsException e) {10 checkForComodification();11 throw new NoSuchElementException();12 }13 }
checkForComodification()方法的实现如下:
1 final void checkForComodification() {2 if (modCount != expectedModCount)3 throw new ConcurrentModificationException();4 }
1 public void remove() { 2 if (lastRet < 0) 3 throw new IllegalStateException(); 4 checkForComodification(); 5 6 try { 7 AbstractList.this.remove(lastRet); 8 if (lastRet < cursor) 9 cursor--;10 lastRet = -1;11 expectedModCount = modCount;12 } catch (IndexOutOfBoundsException e) {13 throw new ConcurrentModificationException();14 }15 }
可以看到,在集合的元素被remove之后,expectedModCount被重新赋值,是的modCount总是等于expectedModCount,所以不会抛出ConcurrentModificationException异常。
而上面提到的第二种使用foreach来对集合进行遍历本质上和第三种情况是一样的,因为根据Oracle提供的文档,foreach内部的实现机制其实就是使用的Iterator。
第一种使用for循环进行遍历时内部使用的就是集合本身的遍历方法,这里不做讨论。
--------------------- 作者:小明的代码世界 来源:CSDN 原文:https://blog.csdn.net/cmder1000/article/details/73865815 版权声明:本文为博主原创文章,转载请附上博文链接!