初始化一个集合
List list = new ArrayList<>(Arrays.asList(1,2,3,4));
一、使用for循环进行删除 (正序遍历移除元素)
- System.out.println("初始化集合大小:" + list.size());
- for (int i = 0; i < list.size(); i++) {
- Integer remove = list.remove(i);
- System.out.println("下标:"+ i +"集合大小:" + list.size() + ":" + "集合元素:" + list);
- }

观察输出:发现集合的size随着remove的次数在变化。
第一次:i < 0 size = 4
第二次:i < 3 size = 3
第三次:i < 2 size = 2 由于 2 < 2 是不成立的,所以for循环不在执行了。这样的话,元素就还剩下两个元素并没有删除。这是第一次坑。
第二个坑,在删除是时候,数组的下标是会变的,第一次的时候[1,2,3,4] 下标0的元素是1
第二次的时候[2,3,4] 下标0的元素是2 ,所以你会发现 第二次的时候 把3删除了 并没有删除2
1.1 升级一下操作
顺序循环时,删除当前位置的值,下一个值就会补到当前位置,所以需要执行i–操作;
- for (int i=0; i
- if (list.get(i) == 3) {
- list.remove(i);
- i--;
- }
- }

二、使用for循环进行删除 (倒序遍历移除元素)
- for (int i = list.size()-1; i >= 0; i--) {
- list.remove(i);
- System.out.println("下标:"+ i +"集合大小:" + list.size() + ":" + "集合元素:" + list);
- }

//i=3 i>=0 移除array[3] list[1,2,3]
//i=2 i>=0 移除array[2] list[1,2]
//i=1 i>=0 移除array[1] list[1]
//i=0 i>=0 移除array[0] list[]
观察输出:倒序的移除结果是正确的。
三、使用foreach循环进行删除
- for (Integer integer : list) {
- list.remove(integer);
- }

出现异常,原因比较多,移步到这篇:https://www.freesion.com/article/68581338545/
四、使用Iterator迭代器进行删除
- Iterator
iterator = list.iterator(); - while (iterator.hasNext()){
- iterator.next();
- iterator.remove();
- System.out.println("Iterator遍历移除元素结果:" + list);
- }

运行结果:运行正常。
删除总结:尽可能用迭代器来遍历,并使用迭代器的remove方法来删除元素。 用for循环的话,就使用倒序遍历删除元素。
Sublist的坑
一、【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异 常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。
- ArrayList
arrayList = new ArrayList<>(); - arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- arrayList.add(4);
- ArrayList
list = (ArrayList) arrayList.subList(1, 3);

说明:subList 返回的是 ArrayList 的内部类 SubList,并不是ArrayList ,而是 ArrayList 的一个视图,对于SubList子列表的所有操作最终会反映到原列表上。
二、在subList场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生 ConcurrentModificationException 异常。
- List
arrayList = new ArrayList<>(); - arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- arrayList.add(4);
- arrayList.add(5);
- List
list = arrayList.subList(1, 3); - for (Integer integer : list) {
- System.out.println(" "+integer);
- }
- System.out.println("进行元素的删除操作");
- arrayList.remove(0);
- System.out.println("list元素:" + list);

ArrayList中有个protected transient int modCount = 0; 用来记录当前ArrayList被修改的次数。
比如add(),remove()等都会导致modeCount增加: ArrayList.subList()会生成一个SubList的对象,SubList中有个对应modCount同步ArrayList中的modeCount: SubList对象每次再遍历时,会将自己的modeCount与ArrayList的modeCount进行对比,如果两个值不一样就会报异常:ConcurrentModificationException