深入了解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对象进行去重,可以按照以下步骤操作:

java 复制代码
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> keyExtractor) {
    Map<Object, Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
1.2. 按照多个字段进行去重

如果我们需要按照多个字段进行去重,可以稍作修改:

java 复制代码
List<Person> uniquePeople = people.stream()
                                  .filter(distinctByKeys(p -> Arrays.asList(p.getId(), p.getName())))
                                  .collect(Collectors.toList());

// 自定义多字段去重比较器
public static <T> Predicate<T> distinctByKeys(Function<? super T, ? extends List<?>> keyExtractors) {
    Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();
    return t -> {
        List<?> keys = keyExtractors.apply(t);
        return seen.putIfAbsent(keys, Boolean.TRUE) == null;
    };
}
2. 其他去重方法

除了使用Java Stream中的distinct()方法结合自定义比较器外,还有其他几种去重方法:

2.1. 利用集合类实现去重

利用HashSetTreeSet来存储不重复的元素。

java 复制代码
List<Person> people = // 获取Person对象的集合

Set<Person> uniquePeople = new HashSet<>(people); // 或者 TreeSet<Person>(Comparator.comparing(Person::getId))
List<Person> uniqueList = new ArrayList<>(uniquePeople);
2.2. 使用第三方库进行去重

使用Google Guava库的Streams类进行去重操作。

java 复制代码
import com.google.common.collect.Streams;

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

List<Person> uniquePeople = Streams.stream(people)
                                   .distinct()
                                   .collect(Collectors.toList());
2.3. 利用Java 8的新特性进行去重

利用Collectors.toMap()方法结合mergeFunction来实现去重。

java 复制代码
List<Person> people = // 获取Person对象的集合

List<Person> uniquePeople = new ArrayList<>(people.stream()
                                                    .collect(Collectors.toMap(Person::getId, Function.identity(), (existing, replacement) -> existing))
                                                    .values());
3. 总结

通过本文的介绍,我们深入了解了Java Stream中的distinct()方法,并探讨了如何按照一个或多个指定对象字段进行去重。除了distinct()方法外,我们还介绍了利用集合类、第三方库以及Java 8的新特性来实现去重的方法。每种方法都有其适用的场景和优缺点,开发者可以根据具体情况选择合适的方法来进行去重。希望本文能够帮助你更好地理解和应用Java中的去重技术。

相关推荐
IOT-Power4 分钟前
QT 对话框(QDialog)中 accept、reject、exec、open的使用
开发语言·qt
froginwe116 分钟前
ASP Session
开发语言
China_Yanhy11 分钟前
AWS S3 深度配置指南:每一栏每个选项有什么作用
java·数据库·aws
lbb 小魔仙14 分钟前
【Python】零基础学 Python 爬虫:从原理到反爬,构建企业级爬虫系统
开发语言·爬虫·python
Swift社区15 分钟前
ArkTS Web 组件里,如何通过 javaScriptProxy 让 JS 同步调用原生方法
开发语言·前端·javascript
Q741_14716 分钟前
海致星图招聘 数据库内核研发实习生 一轮笔试 总结复盘(1) 作答语言:C/C++ 链表 二叉树
开发语言·c++·经验分享·面试·笔试
黄河里的小鲤鱼18 分钟前
拯救草台班子-战略
人工智能·python·信息可视化
秃了也弱了。20 分钟前
FASTJSON库:阿里出品java界json解析库,使用与踩坑记录
java·开发语言·json
_OP_CHEN20 分钟前
【从零开始的Qt开发指南】(十九)Qt 文件操作:从 I/O 设备到文件信息,一站式掌握跨平台文件处理
开发语言·c++·qt·前端开发·文件操作·gui开发·qt文件
Dr.Alex Wang22 分钟前
Google Firebase 实战教学 - Streamlit、Bucket、Firebase
数据库·python·安全·googlecloud