stream流distinct多个字段去重
时间: 2025-02-01 22:47:43 浏览: 82
### 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]。
阅读全文
相关推荐




















