java 迭代遍历 删除_对JAVA集合进行遍历删除时务必要用迭代器

0.情景引出

对新手来说,遍历一个集合时难免会碰到删除操作,直接删除的话,肯定是要抛异常的

1 public static voidmain(String[] args) {2

3 List list = new ArrayList<>();4 for(int i=0;i<10;i++){5 list.add(String.valueOf(i));6 }7 System.out.println(list.toString());8 System.out.println("----------------------");9 for(String str:list){10 if(str.equals("5"))11 list.remove(str);12 }13 //会抛出异常java.util.ConcurrentModificationException

14

15 }

异常的文档说明:

21dc1b424aaf966b992eba0fb1a20ea4.png

所以呢,聪明的你,大概可以找解决方案了,我以前呢倒是会建一个临时的集合C2和需要删减的集合C1一致,一个循环,一个删减,对于迭代器好像都是敬而远之!!

1.问题解决

咳咳,这里呢,就是为了让自己明白点

1 public static voidmain(String[] args) {2

3 List list = new ArrayList<>();4 for(int i=0;i<10;i++){5 list.add(String.valueOf(i));6 }7 System.out.println(list.toString());8

9 System.out.println("----------------------");10

11 Iterator iter =list.iterator();12 while(iter.hasNext()){13 String str =(String) iter.next();14 if(str.equals("5"))15 iter.remove();16 //错误的写法,list.remove(str);,这种类似于上面的

17 }18

19 System.out.println(list);20

21 }

文章到此应该结束了。下面只是补充下,我自己对Iterator的理解

2.扩展Iterator

2.1 我们先来看一下Iterator的api解释:

c081d11affc967d6a324d00e306b7a28.png

这个移除元素的特点看来是与生俱来的吧,

2.2 我们再看一下ArrayList中的Iterator实现:

1 private class Itr implements Iterator{2 /**

3 * Index of element to be returned by subsequent call to next.4 */

5 int cursor = 0;6 /**

7 * Index of element returned by most recent call to next or8 * previous. Reset to -1 if this element is deleted by a call9 * to remove.10 */

11 int lastRet = -1;12 /**

13 * The modCount value that the iterator believes that the backing14 * List should have. If this expectation is violated, the iterator15 * has detected concurrent modification.16 */

17 int expectedModCount =modCount;18 public booleanhasNext() {19 return cursor !=size();20 }21 publicE next() {22 checkForComodification();23 try{24 E next =get(cursor);25 lastRet = cursor++;26 returnnext;27 } catch(IndexOutOfBoundsException e) {28 checkForComodification();29 throw newNoSuchElementException();30 }31 }32 public voidremove() {33 if (lastRet == -1)34 throw newIllegalStateException();35 checkForComodification();36 try{37 AbstractList.this.remove(lastRet);38 if (lastRet

Iterator采用cursor来来维护自已的状态,而上ArrayList采用size属性来维护自已的状态

当size出现变化时,cursor并不一定能够得到同步,除非这种变化是Iterator主动导致的。

从上面的代码可以看到当Iterator.remove方法导致ArrayList列表发生变化时,他会更新cursor来同步这一变化。但其他方式导致的ArrayList变化,Iterator是无法感知的。ArrayList自然也不会主动通知Iterator们,那将是一个繁重的工作。Iterator到底还是做了努力:为了防止状态不一致可能引发的无法设想的后果,Iterator会经常做checkForComodification检查,以防有变。如果有变,则以异常抛出,所以就出现了上面的异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值