对List元素迭代删除的注意事项以及三个方法
来源:互联网 发布:免费视频网站源码 编辑:程序博客网 时间:2024/06/06 00:50
有一个List,里面存储1-100000的数,,写出几种删除是偶数的元素的代码
第一印象是找到list中偶数,对其直接删除
for(int num:list){ if(num%2==0) list.remove(num); }
结果就报了concurrentModificationException,并发修改异常
我们都知道,使用for循环遍历集合,内部会走Iterator,即判断hasNext之后,使用next移动光标到下一个。
看了一下hasNext与next的源码
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size;//游标不等于元素个数就是还有下一个 }public E next() { checkForComodification();//check是否并发修改 int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }}
**modCount是集合添加元素、删除元素的次数,expectedModCount是预期的修改次数。
每次进入next都会判断modCount与expectedModCount是否相等,不相等则抛出并发修改异常**
可以想到,假设起始在list添加100000数据,则modCount为100000,expectedModCount也初始为100000,然而对list直接remove一次之后,删除元素次数就+1了,那么expectedModCount=100001!=modCount,所以报错
而使用Iterator删除元素就不会报错了,比如
方法一:
Iterator<Integer> it = list.iterator(); while(it.hasNext()){ int i=it.next(); if(i%2==0) it.remove(); }
花费600ms
使用it.remove()来删除每一个符合的元素,Iterator会自动修改expectedModCount,使modCount与之相等。
方法二:
先找到符合的元素组成集合,在一次性removeAll
List<Integer> list3 = new ArrayList<>(); for(int num:list){ if(num%2==0){ list3.add(num); } }list.removeAll(list3);
十万条数据花费3000ms+
看到画了3000ms,我面红耳赤,这tm,脑子有问题了,这又是写新集合又是删原集合,还是个ArrayList而不是LinkedList,怎么可能更快,
于是
方法三:
。。。。。突然发现上面代码的list3反过来不就是结果嘛。
List<Integer> list2 = new ArrayList<Integer>(); while(it.hasNext()){ int i=it.next(); if(i%2!=0) list2.add(i); }
这里的list2就是“删完”偶数的list
耗时10ms
- 对List元素迭代删除的注意事项以及三个方法
- Java中List迭代过程中删除、新增元素的处理
- vector 的迭代和删除元素
- 循环删除list中元素的方法
- 集合迭代删除元素
- STL中list,遍历删除元素注意事项
- 对C++ STL,list元素的循环删除操作
- python中对list遍历的过程中删除元素
- 循环删除List元素方法
- 删除正在循环迭代的集合元素的分析
- List对里面元素进行过滤删除
- python中list(元组)删除元素的方法
- C++ set map list的正确删除元素方法
- 遍历List集合同时删除元素的正确方法
- Java编程:删除 List 元素的三种正确方法
- JAVA中循环删除list中元素的方法总结
- JAVA中循环删除list中元素的方法总结
- python中List添加,删除元素的几种方法
- 移动端下载文件或图片(h5+的Downloader下载网络图片缓存到本地的案例)
- 1001. 害死人不偿命的(3n+1)猜想 (15)——C语言
- 交叉验证集和测试集
- HTML5 布局,新标签
- JDBC:使用PreparedStatement防止SQL注入
- 对List元素迭代删除的注意事项以及三个方法
- 申报价值大于等于 2000CNY 时关税预付不能选择是
- HDU 1249 三角形分割平面
- (九)装饰器
- 高级软件工程实验7-----将menu设计为可重用的子系统
- 第3次作业
- HDU 2602-Bone Collector
- LinkedBlockingQueue的put,add跟offer的区别
- 范式的概念和应用(1.2.3.bc.4.5)