为什么for循环中删除元素会报错

有时会遇到这样的业务需要,在 for 循环中删除列表元素,比如下面的例子。


        List<User> userList = userDao.getUserList();
        for(int i = 0; i < userList.size(); i++){
            User user = userList.get(i);
            // 进行退款操作,若退款失败,从列表中删除
            boolean withdraw = true; // 此处省略业务代码
            if(withdraw){
                userList.remove(user);
            }
       }

这样的代码是不报错的,也不会抛出异常。但是当用到迭代器时,会报错。


        List<User> userList = userDao.getUserList();
        for(User user : userList){
            // 进行退款操作,若退款失败,从列表中删除
            boolean withdraw = true; // 此处省略业务代码
            if(withdraw){
                userList.remove(user);
            }
       }

for(User user : userList){} ,这样的代码,可能会抛出异常的。

这个原因是迭代器遍历时,删除未遍历的元素时,源码层面会报错。

具体原因,回头再写一篇文章详细说明。

本篇文章的重点是说 for(int i = 0; i < userList.size(); i++){} 这样不报错,当我写了个demo去验证时,出了幺蛾子。


    public static void main(String[] args) {
        String test = "1,2,3,4,5,6,7";
        List<String> testList = Arrays.asList(test.split(","));
        log.info("testList:{}",testList);
        for(int i = 0; i < testList.size(); i++){
            String temp = testList.get(i);
            if("3".equals(temp)){
                testList.remove(temp);
            }
        }
        log.info("testList:{}",testList);
    }

我知道for循环中,这样删除元素,应该是不报错的,可是demo运行报错了。

在这里插入图片描述
然后我就开始疑惑了,为什么会这样呢? for 循环里,不可以删除么。当我改了一行代码后,以运行了一次


List<String> testList = Arrays.asList(test.split(","));
List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;

    public static void main(String[] args) {
        String test = "1,2,3,4,5,6,7";
        List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;
        log.info("testList:{}",testList);
        for(int i = 0; i < testList.size(); i++){
            String temp = testList.get(i);
            if("3".equals(temp)){
                testList.remove(temp);
            }
        }
        log.info("testList:{}",testList);
    }

这个运行结果


  testList:[1, 2, 3, 4, 5, 6, 7]
  testList:[1, 2, 4, 5, 6, 7]

Process finished with exit code 0

完美运行了,结果符合我预期,for 循环中,删除了一个元素。

我点开了,Arrays.asList 的源码,返回值就是 ArrayList


    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

我感到头大了,头大的是,现在为什么不报错了。下边这两行代码

用第一行报错,用第二行不报错, Arrays.asList 返回的就是一个ArrayList


List<String> testList = Arrays.asList(test.split(","));
List<String> testList = new ArrayList<>(Arrays.asList(test.split(","))) ;

我提醒自己,不是见鬼了,不是见鬼了,一定是我还有东西没想到。

    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

当我点击进行这个new ArrayList<>(a)时,它居然没有跳转到别的类,而是留在了当前类java.util.Arrays 中,

尼马, Arrays这个类中,有一个内部类,叫 ArrayList。此ArrayList,非彼ArrayList。

这时,我才想起来,以前看过文章,提到过 Arrays的这个内部类,今天真的没想起来。

List testList = Arrays.asList(test.split(",")); 用这个的时候,实际调用的是,Arrays这个类的内部类 ArrayList

内部类中,没有remove 这方法。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值