一、问题出现
测试代码
@Test public void listTest(){ List<String> list =new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); removeList0(list); list.forEach(System.out::println); } //直接遍历删除 public void removeList0(List<String> list){ for (String s : list) { if (s.equalsIgnoreCase("c")) { list.remove(s); } } }
测试结果
java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at cn.hangtian.com.PackTest.removeList0(PackTest.java:499) at cn.hangtian.com.PackTest.listTest(PackTest.java:473)
二、问题原因
列表的foreach遍历方法中使用的迭代器中的遍历方法,迭代器还有一个修改列表计数器(modCount);而使用列表的remove()
方法修改的是列表的修改列表计数器,二者值不等导致异常。
三、问题解决
单线程中使用迭代器的remove()方法或者利用索引删除。
1、迭代器删除
测试代码
@Test public void listTest(){ List<String> list =new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); removeList(list); list.forEach(System.out::println); } //通过迭代器删除 public void removeList(List<String> list){ Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ String s = iterator.next(); if (s.equalsIgnoreCase("c")){ iterator.remove(); } } }
测试结果
a b
2、索引方式删除
测试代码
@Test public void listTest(){ List<String> list =new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); removeList(list); list.forEach(System.out::println); } //通过索引删除 public void removeList0(List<String> list){ for (int i = 0; i < list.size(); i++) { if (list.get(i).equalsIgnoreCase("c")) { list.remove(i); } } }
测试结果
a b
PS:多线程中请自行尝试搜索解决。😃