Java8 list多属性去重

大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。

在 Java 开发中,我们经常会面临对 List 中的对象属性去重的需求。然而,当需要根据多个属性来进行去重时,情况会稍微复杂一些。本篇博客将深入探讨如何使用 Java 8 的 Stream API 来实现 List 多属性去重。

前言

在实际开发中,我们常常遇到一个业务场景:有一个 List 集合,其中包含了多个对象,需要根据对象中某个或者某些属性来进行去重操作,以确保 List 中的元素在这些属性的组合下唯一。在 Java 8 中,Stream API 为我我们提供了一些便捷的操作,使得在开发中,效率有所提升。

list 多属性去重

创建一个 RequestDto 类,包含了姓名(name)、 id(主键)、状态(status)三个属性。我们的目标是根据姓名、id和状态这三个属性来对List 进行去重操作。

RequestDto 类:

@Data
public class RequestDto {
    private String name; // 姓名
    private String id; // id
    private String status; // 状态
}

使用stream Api 进行去重,我们先创建一些对象集合:

package com.yin.demo.controller;

import lombok.Data;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;


@Data
public class RequestDto {
    private String name;
    private String id;
    private String status;
}

class demo {
    public static void main(String[] args) {
        List<RequestDto> li = new ArrayList<>();
        RequestDto dto1 = new RequestDto();
        dto1.setId("1");
        dto1.setName("张三");
        dto1.setStatus("1");
        li.add(dto1);

        RequestDto dto2 = new RequestDto();
        dto2.setId("1");
        dto2.setName("张三");
        dto2.setStatus("1");
        li.add(dto2);

        RequestDto dto3 = new RequestDto();
        dto3.setId("1");
        dto3.setName("李四");
        dto3.setStatus("1");
        li.add(dto3);

//        ArrayList<RequestDto> result = li.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
//                () -> new TreeSet<>(Comparator.comparing(o -> o.getId() + o.getName() + o.getStatus()))), ArrayList::new));

        System.out.println(li);

    }
}

打印集合如下:

在这里插入图片描述

使用java8 Stream API进行去重
class demo {
    public static void main(String[] args) {
        List<RequestDto> li = new ArrayList<>();
        RequestDto dto1 = new RequestDto();
        dto1.setId("1");
        dto1.setName("张三");
        dto1.setStatus("1");
        li.add(dto1);

        RequestDto dto2 = new RequestDto();
        dto2.setId("1");
        dto2.setName("张三");
        dto2.setStatus("1");
        li.add(dto2);

        RequestDto dto3 = new RequestDto();
        dto3.setId("1");
        dto3.setName("李四");
        dto3.setStatus("1");
        li.add(dto3);
        
        // java8 Stream 流去重操作通过对属性id、name、status进行去重
        ArrayList<RequestDto> result = li.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(o -> o.getId() + o.getName() + o.getStatus()))), ArrayList::new));

        System.out.println(result);

    }
}

结果如下:可以看出已经成功去重

在这里插入图片描述

根据list中Object某个属性去重

利用 TreeSet 通过 comparing 指定某个属性来去重,例如根据name属性去重

// 核心代码如下,其实就是上面的多属性去重只用到了一个属性
// java8 Stream 流去重操作
        ArrayList<RequestDto> result = li.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(o -> o.getName()))), ArrayList::new));

结果打印如下:

在这里插入图片描述

distinct对某个属性去重

根据对象的某个属性去重,对属性分组后进行 distinct 操作:返回的是去重后的属性集合

// 核心代码如下,返回的是属性
// java8 Stream 流去重操作
        List<String> result = li.stream().map(RequestDto::getName).distinct().collect(Collectors.toList());

打印结果如下:

在这里插入图片描述

distinct对集合去重

// 核心代码如下,返回的是对象
// java8 Stream 流去重操作
        List<RequestDto> result = li.stream().distinct().collect(Collectors.toList());

打印结果如下:

在这里插入图片描述

通过利用 Java 8 的 Stream API,我们可以轻松地实现List多属性去重!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在Java 8中,我们可以使用Stream API和Lambda表达式来根据list对象属性去重。下面是具体步骤: 1. 通过Stream API将list对象转换成Stream流; 2. 使用distinct()方法根据对象属性去重,该方法使用对象的equals()方法判断是否相等; 3. 如果对象类没有重写equals()方法,则需要在该类中重写该方法,以保证根据对象属性去重的正确性; 4. 最后,使用collect()方法将Stream流转换回list对象。 以下是示例代码: ``` // 定义Person类 public class Person { private String name; private int age; // 构造方法和getter/setter方法省略 @Override public boolean equals(Object obj) { // 重写equals()方法 if (obj == this) { return true; } if (!(obj instanceof Person)) { return false; } Person person = (Person) obj; return this.name.equals(person.getName()) && this.age == person.getAge(); } } // 定义list对象 List<Person> personList = Arrays.asList( new Person("Alice", 20), new Person("Bob", 25), new Person("Alice", 20), new Person("Charlie", 30) ); // 根据名称和年龄属性去重 List<Person> distinctPersonList = personList.stream().distinct().collect(Collectors.toList()); ``` 以上代码将根据Person对象的name和age属性去重,最终输出的distinctPersonList为: ``` [Person{name='Alice', age=20}, Person{name='Bob', age=25}, Person{name='Charlie', age=30}] ``` ### 回答2: 在Java 8中,可以使用stream()和distinct()方法对List对象属性进行去重。 首先,我们需要创建一个包含对象的List,例如: ``` List<Person> personList = new ArrayList<>(); personList.add(new Person("Alice", 20)); personList.add(new Person("Bob", 20)); personList.add(new Person("Alice", 25)); ``` 其中,每个Person对象包含两个属性,分别为name和age。我们现在需要根据name属性去重。 我们可以使用以下代码实现: ``` List<Person> distinctList = personList.stream() .filter(distinctByKey(Person::getName)) .collect(Collectors.toList()); public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Map<Object, Boolean> seen = new ConcurrentHashMap<>(); return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } ``` 以上代码中,我们首先对personList使用stream()方法,然后使用filter()方法筛选出根据Person对象的name属性去重后的数据。在filter()方法中,使用distinctByKey()方法从而实现去重。该方法使用了Java 8中的ConcurrentHashMap进行操作,首先根据keyExtractor将name属性作为key,将Boolean.TRUE作为value存入ConcurrentHashMap中,如果putIfAbsent()方法返回null,表示当前元素还未放入ConcurrentHashMap,即为不重复元素,否则返回已存在的元素,即为重复元素。 最后,使用collect()方法将去重后的元素存入distinctList中。我们可以通过打印distinctList的元素数量进行验证去重是否成功。 该方法可以灵活地根据各种属性进行去重,只需更改keyExtractor即可。 ### 回答3: Java 8 提供了非常便捷、高效的方式根据 list 对象的属性去重,主要借助 lambda 表达式和 Stream API 实现。下面讲解具体实现步骤: 1. 定义一个类,作为 list 的元素,并在该类中定义需要去重属性: ``` public class Person { private int id; private String name; //......getters and setters省略 } ``` 2. 创建一个 list,添加元素: ``` List<Person> list = new ArrayList<>(); list.add(new Person(1, "Tom")); list.add(new Person(2, "Jerry")); list.add(new Person(1, "Tom")); list.add(new Person(3, "Lucy")); ``` 此时,list 中包含 4 个元素,其中第 1 个和第 3 个元素 id 属性相同,需要去重。 3. 使用 Stream API 和 lambda 表达式去重: ``` List<Person> distinctList = list.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getId))), ArrayList::new)); ``` 解释一下上述代码的实现思路:首先用 `.stream()` 将 list 转换成 Stream,然后用 `Collectors.collectingAndThen()` 把 Collector 转换成了另一个 Collector,这里直接使用了 `Collectors.toCollection()` 把结果转成 TreeSet(TreeSet 是有序的 Set),并使用 Comparator.comparing 对元素进行比较,根据 id 属性进行去重。 最后,再把结果转换成 ArrayList 即可。 4. 打印去重后的结果: ``` for (Person person : distinctList) { System.out.println(person.getId() + " " + person.getName()); } ``` 此时输出结果如下: ``` 1 Tom 2 Jerry 3 Lucy ``` 由于已经按 id 属性去重,所以输出结果不再包含重复元素。 总结来说,Java 8 根据 list 对象属性去重比较简单,同样的方法也适用于其他属性去重,只需要将 `Comparator.comparing()` 的参数修改为其他属性即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值