package com.gaopengyu; import java.util.ArrayList; import java.util.Iterator; import java.util.List; class Person { int age; String name; Person(int age, String name) { this.age = age; this.name = name; } } //集合在遍历的时候,如果只是删除其中的一个元素,下面所有的普通for循环都是可以的,但是集合中其他元素的后续删除就不行了,因为前面的元素删除导致后续元素的位置发生了改变。 //小细节,有时候很容易就忽视了,但是有时候小细节能让你付出几个小时,甚至一天的经历来解决,遇到就记下来,下次可以快速解决。 public class RemoveWhenTraverseList { public static void main(String[] args) { Person p1 = new Person(11, "Alice"); Person p2 = new Person(12, "Bob"); Person p3 = new Person(13, "cindy"); Person p4 = new Person(14, "doge"); Person p5 = new Person(15, "ela"); List<Person> personList = new ArrayList<Person>(); personList.add(p1); personList.add(p2); personList.add(p3); personList.add(p3); personList.add(p4); personList.add(p5); // 删除一个可以删除多个的时候可以能遗漏(两个要删除的元素相邻的情况下) // useOrdinaryForDelete(personList); // useOrdinaryForDeleteChangei(personList); // useOrdinaryForDeleteReverse(personList); // 这个会报错ConcurrentModificationException。这是list集合中fail-fast机制,出现在集合遍历的时候,改变元素,就会报ConcurrentModificationException,所以利用增强for循环实现该功能是不可行的。 // useEnhancedForDelete(personList); useIteratorDelete(personList); } //常规ListRemove元素时因为remove之后,后边的元素会向前补齐被删掉的位置,但是i仍然是会向前走一步的,所以会漏掉被删除的元素后边的一个元素 public static void useOrdinaryForDelete(List<Person> personList) { for (int i = 0; i < personList.size(); i++) { if ("cindy".equals(personList.get(i).name)) { personList.remove(i); } } for (int i = 0; i < personList.size(); i++) { System.out.println("使用普通for循环删除多条数据之后:" + personList.get(i).name); } } // 第一中解决办法 public static void useOrdinaryForDeleteChangei(List<Person> personList) { for (int i = 0; i < personList.size(); i++) { if ("cindy".equals(personList.get(i).name)) { personList.remove(i); i--; // 在删除的同时,即list里下一个元素向前移动的同时,i跟着向前移动 } } for (int i = 0; i < personList.size(); i++) { System.out.println("使用普通for循环删除多条数据同时改变i值之后:" + personList.get(i).name); } } // 第二中解决办法,逆序同样可以解决 public static void useOrdinaryForDeleteReverse(List<Person> personList) { for (int i = personList.size() - 1; i >= 0; i--) { if ("cindy".equals(personList.get(i).name)) { personList.remove(i); } } for (int i = 0; i < personList.size(); i++) { System.out.println("使用普通for循环逆序删除多条数据之后:" + personList.get(i).name); } } // 使用增强for循环 public static void useEnhancedForDelete(List<Person> personList) { for (Person p : personList) { if ("cindy".equals(p.name)) { personList.remove(p); } } for (int i = 0; i < personList.size(); i++) { System.out.println("使用增强for循环删除多条数据之后:" + personList.get(i).name); } } // 使用Iterator迭代器 public static void useIteratorDelete(List<Person> personList) { Iterator<Person> it = personList.iterator(); while (it.hasNext()) { if ("cindy".equals(it.next().name)) { // 这个和上面的增强for循环一样会报错ConcurrentModificationException // personList.remove(it.next()); // 这个由于iterator的remove方法会同时修改expectedModCount ,所以checkformodification的时候不会出现和modcount不等导致failfast的情况。所以是正确的。 it.remove(); } } for (int i = 0; i < personList.size(); i++) { System.out.println("使用增强for循环删除多条数据之后:" + personList.get(i).name); } } }