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)
并发修改异常是因为,在集合中增删操作会导致 预期数量
和 计数器的数量
不一致,就会导致并发修改异常