周五的时候公司的实习生问我自己写的代码有异常 java.util.ConcurrentModificationException, 我看到他的代码嗯....大概就是这么个情况, 当时我就...
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"A","B","C","D","E","C","C");
for (String s : list) {
if (s.equals("C")){
list.remove(s);
}
}
System.out.println(list);
运行这段代码
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
可以看到, 当两值不相等时 则抛出异常 ConcurrentModificationException()
阿里规范明确表示 : 不要在forEach循环中进行元素的remove/add 操作 !
因为ArrayList是基于数组实现的, 是一个动态数组, 其容量能自动增长. ArrayList 不是线程安全的, 它是通过下标index进行访问的. 所以当你移除第一个C时, 集合大小已经减了1, 当最后移除时, 你的i 就会比集合的下标大, 两值不相等, 抛出异常...
话不多说, 那我们平时遇到类似的代码, 应该如何处理呢 ? (个人处理集合时 比较喜欢用stream)
- stream
- removeIf
- iterator
- removeAll
看代码吧
// stream
List<String> notContainEleC = list.stream().filter(item -> !"C".equals(item)).collect(Collectors.toList());
System.out.println("stream" + notContainEleC);
// removeIf
list.removeIf(item -> item.equals("C"));
System.out.println("removeIf" + list);
// iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if ("C".equals(next)){
iterator.remove();
}
}
System.out.println("iterator" + list);
// removeAll
ArrayList<String> strings = new ArrayList<>(); //Arrays.asList("C")不行
strings.add("C");
list.removeAll(strings);
System.out.println("removeAll" + list);
推荐阅读