深入了解Java Stream中的distinct()方法:按一个或多个指定对象字段进行去重

深入了解Java Stream中的distinct()方法:按一个或多个指定对象字段进行去重

在Java编程中,Stream API为我们提供了丰富的操作方法来处理集合数据。其中,distinct()方法是一种常用的方法,用于去除Stream中的重复元素。然而,有时我们可能需要按照对象的一个或多个字段进行去重。本文将探讨如何利用Java Stream中的distinct()方法按照指定对象字段进行去重,并介绍其他几种实现去重的方法。

1. Java Stream中的distinct()方法

distinct()方法是Stream API中的一个中间操作,它返回一个去除了重复元素的新Stream。默认情况下,它使用对象的equals()方法来判断元素是否相等。但是,如果我们需要按照对象的特定字段来进行去重,就需要结合使用distinct()方法和自定义比较器。

1.1. 按照单个字段进行去重

假设我们有一个Person类,其中包含idname两个字段。我们想要按照id字段对Person对象进行去重,可以按照以下步骤操作:

List<Person> people = // 获取Person对象的集合

List<Person> uniquePeople = people.stream()
                                  .filter(distinctByKey(Person::getId))
                                  .collect(Collectors.toList());

// 自定义去重比较器
public static <T> Predicate<T> distinctByKey(Function<? super T, Object>
### Java Stream API 多个字段 为了实现基于多个字段操作,可以利用 `Stream` 的 `distinct()` 方法结合自定义比较器来完成。由于默认的 `distinct()` 只能除完全相同的对象,因此需要通过创建一个新的类并覆盖其 `equals()` 和 `hashCode()` 方法者使用 `Collectors.toMap()` 来达到目的。 #### 使用 `toSet()` 结合自定义键 一种方法是先转换成 Map 并指定 key 作为要依据的属性组合: ```java import java.util.*; import java.util.stream.Collectors; class Person { private String firstName; private String lastName; public Person(String fName, String lName){ this.firstName = fName; this.lastName = lName; } @Override public boolean equals(Object o) { ... } // 实现此逻辑 @Override public int hashCode() { ... } // 实现此逻辑 // Getters & Setters... } List<Person> people = Arrays.asList( new Person("John", "Doe"), new Person("Jane", "Smith"), new Person("John", "Doe") // Duplicate entry ); // Remove duplicates based on first name and last name. people.stream() .collect(Collectors.toMap( p -> p.getFirstName() + "-" + p.getLastName(), Function.identity(), (existing, replacement) -> existing)) .values(); ``` 上述代码片段展示了如何根据两个字符串类型的字段(firstName 和 lastName)来进行复项移除[^1]。 另一种更通用的方法是在流处理过程中直接应用过滤条件: ```java public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); // Thread-safe set return t -> seen.add(keyExtractor.apply(t)); } people.stream().filter(distinctByKey(p -> p.getFirstName() + "-" + p.getLastName())).toList(); ``` 这段代码提供了一个可复用的帮助函数 `distinctByKey` ,它接受一个提取唯一键的功能接口参数,并返回一个谓词用于筛选掉那些已经遇到过的记录[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值