初始化一个集合

List<Integer> 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);
 }

ios for循环里remove for循环remove list_for循环

 观察输出:发现集合的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<list.size(); i++) {
        if (list.get(i) == 3) {
            list.remove(i);
            i--;
        }
    }

ios for循环里remove for循环remove list_java_02

 

二、使用for循环进行删除 (倒序遍历移除元素)

for (int i = list.size()-1; i >= 0; i--) {
    list.remove(i);
    System.out.println("下标:"+ i +"集合大小:" + list.size() + ":" + "集合元素:" + list);
}

ios for循环里remove for循环remove list_System_03

//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);
}

ios for循环里remove for循环remove list_for循环_04

 出现异常,原因比较多,移步到这篇:https://www.freesion.com/article/68581338545/

四、使用Iterator迭代器进行删除 

Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
    iterator.next();
    iterator.remove();
    System.out.println("Iterator遍历移除元素结果:" + list);
}

ios for循环里remove for循环remove list_for循环_05

 运行结果:运行正常。

删除总结:尽可能用迭代器来遍历,并使用迭代器的remove方法来删除元素。 用for循环的话,就使用倒序遍历删除元素。

Sublist的坑

   一、【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异 常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
ArrayList<Integer> list = (ArrayList<Integer>) arrayList.subList(1, 3);

ios for循环里remove for循环remove list_java_06

说明:subList 返回的是 ArrayList 的内部类 SubList,并不是ArrayList ,而是 ArrayList 的一个视图,对于SubList子列表的所有操作最终会反映到原列表上。 

二、在subList场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生 ConcurrentModificationException 异常。

List<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
arrayList.add(5);
List<Integer> list = arrayList.subList(1, 3);
for (Integer integer : list) {
    System.out.println(" "+integer);
}
System.out.println("进行元素的删除操作");
arrayList.remove(0);
System.out.println("list元素:" + list);

ios for循环里remove for循环remove list_for循环_07

 ArrayList中有个protected transient int modCount = 0; 用来记录当前ArrayList被修改的次数。

比如add(),remove()等都会导致modeCount增加: ArrayList.subList()会生成一个SubList的对象,SubList中有个对应modCount同步ArrayList中的modeCount: SubList对象每次再遍历时,会将自己的modeCount与ArrayList的modeCount进行对比,如果两个值不一样就会报异常:ConcurrentModificationException