Java 8由属性区分 [英] Java 8 Distinct by property
问题描述
在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的默认等式检查
object,所以我需要像
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
是一个有状态过滤器。写函数返回一个谓词,它也维护了之前看到的状态,并返回给定元素是否第一次被看到:
I finally figured out a nice way to do this. Consider distinct
to be a stateful filter. Write function that returns a predicate that also maintains state about what it's seen previously, and returns whether the given element was seen for the first time:
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;
}
然后您可以写:
persons.stream().filter(distinctByKey(p -> p.getName());
注意:这与本问题的我的回答基本相同:任意键上的Java Lambda Stream Distinct()?
Note: this is essentially the same as my answer to this question:Java Lambda Stream Distinct() on arbitrary key?
这篇关于Java 8由属性区分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!