List 删除属性为指定值的对象的3种方法

List 删除属性为指定值的对象的3种方法

这本是一个很基础的问题,只有底层基础扎实了,才能造更好的上层建筑,正好我自己在学stream的是由也是一脸懵,正好写系统是遇到了这么个场景,写个文章小记一下。

一、数据准备

首先,要处理的列表如下:


@Data
@AllArgsConstructor
class ListItem{
    private int id;
    private String name;
}

List<ListItem> list = new ArrayList<>(4);
list.add(new ListItem(1,"张三"));
list.add(new ListItem(2,"李四"));
list.add(new ListItem(3,"李四"));
list.add(new ListItem(4,"王五"));

需求是删除名字为李四ListItem

二、一个错误的实践案例:

/**
* 按照索引检索
*/
@Test
void testListRemoveByIndex(){
    List<ListItem> list = new ArrayList<>(4);
    list.add(new ListItem(1,"张三"));
    list.add(new ListItem(2,"李四"));
    list.add(new ListItem(3,"李四"));
    list.add(new ListItem(4,"王五"));

    for (int i = 0; i <list.size(); i++) {
        if (list.get(i).getName().equals("李四")) {
            list.remove(i);
        }
    }
    System.out.println(list);
}

以下为输出结果:

[ServiceTest.ListItem(id=1, name=张三), ServiceTest.ListItem(id=3, name=李四), ServiceTest.ListItem(id=4, name=王五)]

结果上来看,并没有实现我们预期的效果,俗称BUG.

三、正确的操作步骤

以上出问题的原因,这个可以自己分析一下,再或者通过debug 打断点的方式就能明白,另外还有就是通过for循环,进行删除的方式。这里不做赘述了,主要说一下以下两种方式。

1.iterator删除,遍历到元素,删除

/**
     * 使用迭代器删除
     */
    @Test
    void testListRemoveByIterator(){
        List<ListItem> list = new ArrayList<>(4);
        list.add(new ListItem(1,"张三"));
        list.add(new ListItem(2,"李四"));
        list.add(new ListItem(3,"李四"));
        list.add(new ListItem(4,"王五"));

        Iterator<ListItem> iterator = list.iterator();
        while (iterator.hasNext()){
            ListItem next = iterator.next();
            if ("李四".equals(next.getName())) {
                iterator.remove();
            }
        }
        System.out.println(list);
    }

以下为输出结果:

[ServiceTest.ListItem(id=1, name=张三), ServiceTest.ListItem(id=4, name=王五)]

2.stream.filter 过滤掉指定id的元素,重新组合

    /**
     * 使用stream filter
     */
    @Test
    void testListRemoveByStreamFilter(){
        List<ListItem> list = new ArrayList<>(4);
        list.add(new ListItem(1,"张三"));
        list.add(new ListItem(2,"李四"));
        list.add(new ListItem(3,"李四"));
        list.add(new ListItem(4,"王五"));

        list = list.stream().filter(e->!"李四".equals(e.getName())).collect(Collectors.toList());

        System.out.println(list);
    }

以下为输出结果:

[ServiceTest.ListItem(id=1, name=张三), ServiceTest.ListItem(id=4, name=王五)]

不用纠结,这俩方法都挺好。现在硬件这么牛了。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注