java中list在遍历过程中有几种删除元素的方式?

98 阅读1分钟

List是我们在工作场景中使用的类型中最多的一个啦,有很多场景需要我们在List中删除一个或某个元素,那么我们该如何正确无误的删除List中的元素呢,下面通过学习老项目中前辈们留下的代码总结出如下几种方式

准备数据,我们通过代码来说明,首先我们需要准备一下数据

    List<String> list = new ArrayList<>();

    @Before
    public void init() {
        list.add("zhangsan1");
        list.add("zhangsan2");
        list.add("lisi1");
        list.add("lisi2");
        list.add("wangwu1");
        list.add("wangwu2");
        list.add("zhaoliu1");
        list.add("zhaoliu2");
    }

通过for循环-不可取的方式

直接使用简单for循环,这种方式可能会在遍历的过程中漏掉部分元素,从而出现少删的情况

@Test
    public void by_remove_fist() {
        // 这样实现有问题,模拟删除第一个元素
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).startsWith("zhangsan1")) {
                list.remove(i);
            }
        }
        List<String> expected = Arrays.asList("zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2", "zhaoliu1", "zhaoliu2");
        Assert.assertThat(expected, CoreMatchers.is(list));
    }

    @Test
    public void by_remove_last() {
        // 这样实现有问题,模拟删除最后一个元素
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).startsWith("zhaoliu")) {
                list.remove(i);
            }
        }
        List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2", "zhaoliu2");
        Assert.assertThat(list, CoreMatchers.is(expected));
    }

    @Test
    public void by_remove_middle() {
        // 这样实现有问题,模拟删除中间元素
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).startsWith("lisi")) {
                list.remove(i);
            }
        }
        List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi2", "wangwu1", "wangwu2", "zhaoliu1", "zhaoliu2");
        Assert.assertThat(list, CoreMatchers.is(expected));
    }

通过Stream的Filter

    @Test
    public void by_stream_filter() {
        list = list.stream().filter(t -> !t.startsWith("zhaoliu")).collect(Collectors.toList());
        List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
        Assert.assertThat(list, CoreMatchers.is(expected));
    }

通过removeIf

    @Test
    public void by_removeIf() {
        list.removeIf(t -> t.startsWith("zhaoliu"));
        List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
        Assert.assertThat(list, CoreMatchers.is(expected));
    }

通过Iterator

迭代器:迭代其实我们可以简单地理解为遍历,是一个标准 化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向每次遍历前都需要知道要遍历集合的内部结构。

    @Test
    public void by_iterator() {
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String s = iterator.next();
            if (s.startsWith("zhaoliu")) {
                iterator.remove();
            }
        }
        List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
        Assert.assertThat(list, CoreMatchers.is(expected));
    }