在Java中删除集合中元素时,需要特别注意,一方面是因为,Java是并发编程语言,如果存在并发操作,则会出现逻辑异常;另一方面,在List中删除元素,如果操作不当,则会抛出异常。
阿里推出的《Java开发手册》中的编程规范要求:不要在 foreach 循环里进行元素的 remove/add 操作。对应描述如下:

【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator
方式,如果并发操作,需要对 Iterator 对象加锁。
正例:
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) { String item = iterator.next(); if (删除元素的条件) { iterator.remove(); }
}
反例:
for (String item : list) { if ("1".equals(item)) { list.remove(item); }
}
说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?

Collection中删除元素

Collection中删除元素时,可以直接调用remove方法。但是,如果在forEach循环中删除元素,则会报错。错误示例如下:

public void removeElement() {List<String> list = new LinkedList<>();list.add("1");list.add("2");list.add("3");for (String item : list) {if ("1".equals(item)) {list.remove(item);}}
}

直觉上,上述代码不会有问题,就是在遍历List的时候,删除指定元素。但是,这种方法将会导致运行时异常。异常堆栈如下图所示。

查看异常堆栈,发现是执行checkForComodification校验时,抛出并发修改异常。对应代码如下:

final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();
}

也就是说,在forEach中增加或删除元素时,会进行并发修改校验。所以,不应在forEach中对Collection执行元素增加/删除操作。如果需要在forEach中增加或删除元素,可以使用Iterator,示例代码如下:

public void removeElement() {List<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String item = iterator.next();if ("1".equals(item)) {iterator.remove();}}
}

Java 8 以后,Collection新增removeIf用来实现循环中元素删除。示例代码如下:

public void removeElement() {List<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");list.removeIf(item -> "1".equals(item));
}

分析removeIf可知,其实现就是使用Iterator。源码如下:

default boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);boolean removed = false;final Iterator<E> each = iterator();while (each.hasNext()) {if (filter.test(each.next())) {each.remove();removed = true;}}return removed;
}

当然,也可使用java 8的Stream接口的filter方法来过滤并生成新Collection的方式,此处不再赘述,有兴趣的同学可以自行练习使用。

Map中删除元素

与Collection一样,在Map中删除元素时,可以直接调用remove方法。但是,如果在forEach循环中删除元素,则会报错。错误示例如下:

public void removeElement() {Map<String, String> map = new HashMap<>();map.put("1", "1");map.put("2", "2");map.put("3", "3");map.entrySet().forEach(entry -> {if("1".equals(entry.getKey())){map.remove("1");}});
}

执行上述代码抛出的异常和使用forEach遍历并删除Collection中元素抛出异常一致,这里不再重复说明map中同样可以通过Iterator在Map中删除元素。示例代码如下:

public void removeMapElement() {Map<String, String> map = new HashMap<>();map.put("1", "1");map.put("2", "2");map.put("3", "3");Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();while(it.hasNext()){Map.Entry<String, String> entry = it.next();if(entry.getKey() == "1") {it.remove();}}
}

参考

《Java开发手册》 嵩山版 阿里巴巴
https://blog.csdn.net/hu18315778112/article/details/124321602 List集合for循环删除元素
https://www.cnblogs.com/cchilei/p/13099203.html map循环删除某个元素

Java集合中元素删除相关推荐

  1. Java 集合中遍历删除元素抛异常的原因,从ArrayList说起

    文章目录 使用for删除遗漏元素的原因: 使用foreach删除报错的原因: 其它集合的删除方法 删除集合元素的工具类 ArrayList删除元素的方式. 使用for循环删除.会遗漏删除的元素 使用f ...

  2. java set遍历删除元素_java中循环遍历删除List和Set集合中元素的方法

    今天在做项目时,需要删除List和Set中的某些元素,当时使用边遍历,边删除的方法,却报了以下异常: ConcurrentModificationException 为了以后不忘记,使用烂笔头把它记录 ...

  3. 如何将java集合中重复的元素取出来

    今天就给大家讲一下如何将java集合中重复的元素取出来 不多废话,直接代码 此处是对集合中的数字进行查找,其他类型照样适用! List<Integer> list = new ArrayL ...

  4. Java求两集合中元素交集的四种方法对比总结

    hello,你好呀,我是灰小猿,一个超会写bug的程序猿! 最近在做项目的时候有用到对两个集合中的元素进行对比求其交集的情况,因为涉及到的数据量比较大,所以在进行求两个集合中元素交集的时候,就应该考虑 ...

  5. Java 集合框架分析:JAVA集合中的一些边边角角的知识

    相关文章: Java 集合框架分析:Set http://blog.csdn.net/youyou1543724847/article/details/52733723 Java 集合框架分析:Lin ...

  6. Java - Java集合中的安全失败Fail Safe机制 (CopyOnWriteArrayList)

    文章目录 Pre 概述 fail-safe的容器-CopyOnWriteArrayList add remove函数 例子 缺陷 使用场景 Pre Java - Java集合中的快速失败Fail Fa ...

  7. 三十九、Java集合中的HashSet和TreeSet

    @Author:Runsen @Date:2020/6/6 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  8. java集合提取最小的日期_提取Java集合的元素-Java 8方法

    java集合提取最小的日期 我们都广泛使用了Collection类,例如List,Map及其派生版本. 每次使用它们时,我们都必须遍历它们以找到某个元素或更新这些元素,或者找到匹配某个条件的不同元素. ...

  9. 提取Java集合的元素-Java 8方法

    我们所有人都广泛使用了Collection类,例如List,Map及其派生版本. 每次使用它们时,我们都必须遍历它们以找到某个元素或更新这些元素,或者找到匹配某个条件的不同元素. 考虑如下所示的人员列 ...

最新文章

  1. 模型加速--CLIP-Q: Deep Network Compression Learning by In-Parallel Pruning-Quantization
  2. MVC中的验证和异常处理以及手工激活验证
  3. 全球 Top 10 高材生赴神策数据的交流访问之旅
  4. 2008年汶川大地震中的SAP成都研究院
  5. 从零开始学C++之STL(八):函数对象、 函数对象与容器、函数对象与算法
  6. Ubuntu中用gedit保存文件失败的解决办法
  7. golang的new函数_new()和make()函数以及Golang中的示例
  8. 基于UPS效率进行准确的效用成本分析
  9. struts2.2 json配置
  10. LeetCode 344. Reverse String(反转字符串)
  11. 中南大学计算机学院羽毛球赛,我校第四届“四海一家亲”羽毛球邀请赛成功举行...
  12. 有限元分析类毕业论文文献(推荐10篇)
  13. PHP爬虫之phpspider
  14. saved_model_cli查看SavedModel
  15. bzoj 1260涂色 题解
  16. 思维导图:从Xmind到docsify博客
  17. android 系统级闹铃,Android 设置系统闹铃和日历
  18. 【CSDN年度之“战”征文】机器学习该怎么学?
  19. Docker学习之三:docker镜像管理
  20. wx小程序工具下载及安装

热门文章

  1. 推荐一本Vue源码阅读书籍《Vue.js技术内.幕》
  2. rookie的2019
  3. opencv cv2.imwrite()将视频切割成图片保存失败 + 以及按秒切帧代码
  4. 供应商与企业签订的保密协议
  5. suds调用webservice,option设置
  6. 香港美食攻略(10)——香港仔鱼蛋王★
  7. SQL语句case函数
  8. 【Redis】Redis 分布式锁误删问题
  9. 【题解】[COCI2020-2021#1] Tenis
  10. 在百度AI快车道的技术大佬“偷师学艺”,南京的“手艺人”都报名了!