Java 8 按属性区分 [英] Java 8 Distinct by property

查看:24
本文介绍了Java 8 按属性区分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Java 8 中,如何使用 Stream API 通过检查每个对象的属性的独特性来过滤集合?

In Java 8 how can I filter a collection using the Stream API by checking the distinctness of a property of each object?

例如我有一个 Person 对象列表,我想删除同名的人,

For example I have a list of Person object and I want to remove people with the same name,

persons.stream().distinct();

将对 Person 对象使用默认的相等性检查,所以我需要类似的东西,

Will use the default equality check for a Person object, so I need something like,

persons.stream().distinct(p -> p.getName());

不幸的是,distinct() 方法没有这样的重载.不修改 Person 类内部的相等性检查是否可以简洁地做到这一点?

Unfortunately the distinct() method has no such overload. Without modifying the equality check inside the Person class is it possible to do this succinctly?

推荐答案

distinct 视为 有状态过滤器.这是一个函数,它返回一个谓词,该谓词维护关于它之前看到的内容的状态,并返回给定元素是否第一次被看到:

Consider distinct to be a stateful filter. Here is a function that returns a predicate that maintains state about what it's seen previously, and that returns whether the given element was seen for the first time:

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

然后你可以写:

persons.stream().filter(distinctByKey(Person::getName))

请注意,如果流是有序的并且并行运行,这将在重复项中保留一个任意元素,而不是第一个,如distinct() 确实如此.

Note that if the stream is ordered and is run in parallel, this will preserve an arbitrary element from among the duplicates, instead of the first one, as distinct() does.

(这与这个问题的我的回答基本相同:Java Lambda Stream Distinct() 在任意键上?)

(This is essentially the same as my answer to this question: Java Lambda Stream Distinct() on arbitrary key?)

这篇关于Java 8 按属性区分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆