浅谈List使用的一个易错点

这个问题还是我去年在项目中遇到的,一直没来得及总结。最近同事在他的项目中遇到了类似的问题,让我感觉到有必要总结一下这个易错点。

首先贴上测试代码吧。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class DeleteList {

    public static void main(String[] args) {
        // ArrayList测试
        ArrayList<Integer> arrayList = new ArrayList<Integer>();        
        arrayList.add(0);
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
//      printAndDelete(arrayList);  //(1)
//      printAndDeleteWithIterator(arrayList);  //(2)   
//      printAndDeleteWithListIterator(arrayList); //(3)

        // LinkedList测试
        LinkedList<Integer> linkedList = new LinkedList<Integer>();
        linkedList.add(0);
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
//      printAndDelete(linkedList); //(4)
//      printAndDeleteWithIterator(linkedList); //(5)
//      printAndDeleteWithListIterator(linkedList); //(6)
    }

    /* 直接打印后删除  */
    public static void printAndDelete(List<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
            list.remove(i);
        }
    }

    /* 通过迭代器来实现打印后删除  */
    public static void printAndDeleteWithIterator(List<Integer> list){
        Iterator<Integer> iterable = list.iterator();
        while(iterable.hasNext()) {
            System.out.println(iterable.next());
            iterable.remove();
        }
    }

    /* 通过List专有迭代器来实现打印后删除  */
    public static void printAndDeleteWithListIterator(List<Integer> list) {
        ListIterator<Integer> listIterator = list.listIterator();
        while(listIterator.hasNext()) {
            System.out.println(listIterator.next());
            listIterator.remove();
        }
    }

}

在以上代码中,运行printAndDelete(List<Integer> list) 方法你会发现,只打印了0和2两个数字,可能咋一看不是很好理解。现在我们通过debugger模式来进行简单分析:
(1) 当i=0时
List数据的状态如下图所示:
这里写图片描述

从图中可以看出,此时List的size为4,索引i=0所对应的值为0。

(2) 当i=1时
在执行一遍循环后,i=1,此时List数据的状态如下图所示:
这里写图片描述

从图中可以看出,此时List的size变成了3,并且数据的索引相对于前一个状态发生了变化,这是因为上一遍循环中删除了一个元素。此时索引i=1对应的值为2。

(3) 当i=2时
在执行完第二遍循环后,i=2,此时List数据的状态如下图所示:
这里写图片描述

从图中可以看出,此时List的size变成了2,并且数据的索引相对于前一个状态发生了变化,这是第二遍循环中又删除了一个元素。此时i小于list.size()不再成立,退出循环。

综上,我们可以发现,第二个元素和第四个元素并没有被访问。回到开篇时我讲到的,这个问题还是在项目中发现的,当时的情况就是在删除之前对List 的元素做了一些处理,然后发现并不是所有元素都得到了处理。在此总结,希望可以给你提个醒。

那么解决这个问题的办法就是使用迭代器来遍历和处理List中的元素,这样就不会发生这个问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值