Java循环删除List中元素的正确方式

前言:

最近整理笔记时,发现有几个有意思的常犯错误,在此分享下。

问题:如何批量删除List中的元素呢?
比如:List大小为100,只删除前50个,怎么办?

一.通过for循环删除(错误)

List<Integer> list = new ArrayList<Integer>(Arrays.asList(10,20,30,40,50,60,70,80));
for (int i = 0; i < list.size(); i++) {
            list.remove(i);
            System.out.println("当前值:"+list.get(i)+",执行次数"+i);
}

执行结果:仅删除了list长度值一半的数据

当前值:20,执行次数0
当前值:40,执行次数1
当前值:60,执行次数2
当前值:80,执行次数3

原因:
因为在remove时,List的大小(size)就会缩减,同时也改变了索引的指向,所以无法全部批量删除。

二.使用foreach循环删除(错误)

List<Integer> list = new ArrayList<Integer>(Arrays.asList(10,20,30,40,50,60,70,80));
int m = 1;
for (Integer obj : list) {
    list.remove(obj);
    System.out.println("当前值:" + obj + ",执行次数" + m++);
}

执行结果:抛异常

当前值:10,执行次数1
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)

原因:
在 foreach循环中,编译器使得 remove()方法先于next()方法被调用,这就导致了ConcurrentModificationException 异常。所以抛异常。

三.使用Iterator迭代器删除(正确)

int i = 0;
List<Integer> list = new ArrayList<Integer>(Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80));
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
    Integer num = iterator.next();//必须在remove()之前,显式调用next()
    iterator.remove();
    System.out.println("当前值:" + num + ",执行次数" + ++i);
}

执行结果:全部成功删除

当前值:10,执行次数1
当前值:20,执行次数2
当前值:30,执行次数3
当前值:40,执行次数4
当前值:50,执行次数5
当前值:60,执行次数6
当前值:70,执行次数7
当前值:80,执行次数8

注意:

  • iterator.next()必须在iterator.remove()之前显式调用。
    否则编辑器默认会先调用iterator.remove(),再调用iterator.next(),抛出以下异常:
Exception in thread "main" java.lang.IllegalStateException
    at java.util.ArrayList$Itr.remove(ArrayList.java:864)
    at com.darwin.junit.Calculator.main(Calculator.java:69)

猜你喜欢

转载自blog.csdn.net/x541211190/article/details/79599582