for 循环中删除 List 集合元素
正确删除元素的方式是使用迭代器(Iterator),代码如下:
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
// 删除元素
iterator.remove();
}
JDK8后lambda写法:list.removeIf(s -> s.contains("a"));
正确答案
先上正确答案
public static void main(String[] args) {
List<String> list = new ArrayList<>(4);
list.add("a");
list.add("ab");
list.add("abc");
list.add("abcd");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().contains("a")) {
// 删除元素
iterator.remove();
}
}
System.out.println(list);
}
输出结果为
[]
错误答案1:普通for循环(for-i)
public static void main(String[] args) {
List<String> list = new ArrayList<>(4);
list.add("a");
list.add("ab");
list.add("abc");
list.add("abcd");
for (int i = 0; i < list.size(); i++) {
if (list.get(i).contains("a")) {
list.remove(i);
}
}
System.out.println(list);
}
输出结果为
[ab, abcd]
BUG原因:索引为i的元素删除后,后边元素的索引自动向前补位,即原来索引为i+1的元素,变为了索引为i的元素,但是下一次循环取的索引是i+1,此时你以为取到的是原来索引为i+1的元素,其实取到是原来索引为i+2的元素。
错误答案2:增强for循环(foreach)
public static void main(String[] args) {
List<String> list = new ArrayList<>(4);
list.add("a");
list.add("ab");
list.add("abc");
list.add("abcd");
for (String str : list) {
if (str.contains("a")) {
list.remove(str);
}
}
System.out.println(list);
}
运行报错:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at top.oldmoon.learn.test.ListTest.main(ListTest.java:24)
并发修改异常是因为,在集合中增删操作会导致 预期数量和 计数器的数量不一致,就会导致并发修改异常
预期数量
计数器的数量
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2022-03-07 Spring事务的基本原理
2022-03-07 不用任何框架,Java 就能实现定时任务的 3 种方法