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

查看:363
本文介绍了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的默认等式检查 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屋!

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