ArrayList 的remove

之前在项目中看到这样一段代码,大概的业务逻辑就是移除集合中的元素

List<String> list=new ArrayList<>();
//add
for (int i=0;i<list.size();i++){
            //判断条件
            if(list.get(i).equals("")){
                list.remove(i);
            }
        }

看似简短的代码好像没什么毛病,其实这里面有一个坑。测试一下

List<String> list=new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("2");
        list.add("3");
        for (int i=0;i<list.size();i++){
            //判断条件
            if(list.get(i).equals("2")){
                list.remove(i);
            }
        }
        System.out.println(list);

[1, 2, 3]

我们发现,其中元素“2”并没有移除干净,这是为什么呢?
我们知道ArrayList是一个动态数组,先看一下ArrayList的remove方法。

 public E remove(int index) {
        //检测参数是否下标越界
        rangeCheck(index);
        //记录变更次数
        modCount++;
        //即将被移除的元素
        E oldValue = elementData(index);
        //这个变量实际代表的意义是,实际remove操作是否需要改变数组的结构
        //如果下标不是数组的最后一位元素,那么将改变数组的结构
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

原因找到了,原来在remove操作的时候改变了数组的结构,在遍历的时候遗漏了那些往前窜的元素。

解决办法

-倒序遍历

for (int i=list.size()-1;i>=0;i--){
            //判断条件
            if(list.get(i).equals("2")){
                list.remove(i);
            }
        }

-java8新特性(产生一个新的集合)

 List<String> collect = list.stream().filter(s -> {
            return !s.equals("2");
        }).collect(Collectors.toList());

-迭代器

Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (iterator.next().equals("2")) {
                iterator.remove();
            }
        }

-removeAll方法

list.removeAll(Collections.singletonList("2"));

[1, 3]

posted @   0更新  阅读(125)  评论(0编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示