当前位置:   article > 正文

集合边遍历(for循环)边删除为什么删不干净 及三种实现删除的方法_for (int i = 0; i < list.size(); i++) { list.remov

for (int i = 0; i < list.size(); i++) { list.remove(i); } system.out.println


为什么说数组边for循环遍历边删除会出现删不干净的情况

1、为什么删不干净

先写一个例子:可以先猜一下控制台会打印出什么内容?

public class removeIterator {

    public static void main(String[] args) {
    //ArrayList的底层数据结构就是数组
        List<String>list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        for(int i=0;i<list.size();i++){
            list.remove(i);
        }
        System.out.println(list.toString());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

公布答案:
在这里插入图片描述
可以看到,并没有全部移除掉(猜对没?)。那这是为什么呢?

一开始,list中是这样的:
在这里插入图片描述

当移除下标为0的元素后,index+1=1,而元素bbb及之后的元素都向前移动了一位,如下图:
在这里插入图片描述
接下来要移除index==1位置上的元素,也就是移除ccc,移除ccc后,ddd的下标变为1,而index+1=2,即不会移除ddd,所以最后list剩下了bbb和ddd:
在这里插入图片描述

那么如何才可以稳定的删除呢,总结了以下三种方法:

倒序删

倒序删不会出现上面例子中元素数组位置改变的情况。

public class removeIterator {

    public static void main(String[] args) {
        List<String>list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        for(int i=list.size()-1;i>=0;i--){
            list.remove(i);
        }
        System.out.println(list.toString());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

结果:
在这里插入图片描述
移除指定元素:

 public static void descRemove(List<Integer>list,Integer val){
        for(int i=list.size()-1;i>=0;i--){
            if(list.get(i)==val){
                list.remove(i);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

迭代器

使用 Iterator.remove() 方法
简单介绍一下这个方法:

  1. Collection接口实现了Iterable接口,实现了Iterable接口的类可以拥有增强for循环
  2. Iterator的remove()方法优势
    如果知道删除项的准确位置,删除操作的开销小
    不能对正在被遍历的集合进行改变(add,remove,clear等操作),但是可以调用iterator中的remove方法进行删除
public class removeIterator {

    public static void main(String[] args) {
        List<String>list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            it.next();
            it.remove();
        }
        System.out.println(list.toString());
    }
}

-----结果-----
[]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

注:如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException

删除指定元素:

List<Integer>list=new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(6);
        list.add(3);
        System.out.println(list.size());
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            if( iterator.next().equals(3)){
                iterator.remove();
            }
        }
        System.out.println(list.toString()+":size="+list.size());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

lambda表达式删除

上面使用迭代器的方式虽然能够正常的删除列表中的元素,但是不够优雅,因为要写好几行的遍历代码,显得略臃肿。能不能只用一行代码完成这个功能呢?答案是可以的——使用Lambda表达式:
删除指定条件的元素:

  public String getString(List<Integer> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        list.removeIf(e -> isNotValid(e));
        return list.stream().map(String::valueOf).collect(Collectors.joining(","));
    }

    private static Boolean isNotValid(Integer in) {
        if (in == null) {//为空的为无效数字
            return true;
        }
        return false;
    }
//输入:[1,2,3,null,5,null,7]
//输出:"1,2,3,5,7"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

示例2

 public static void lambdaRemove(List<Integer>list,Integer val){
        list.removeIf(e->e==val);
    }
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/958020
推荐阅读
相关标签
  

闽ICP备14008679号