在Java 8中,我如何使用流API通过检查每个对象的属性的清晰度来过滤一个集合?

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

persons.stream().distinct();

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

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

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


当前回答

你可以使用StreamEx库:

StreamEx.of(persons)
        .distinct(Person::getName)
        .toList()

其他回答

你可以使用StreamEx库:

StreamEx.of(persons)
        .distinct(Person::getName)
        .toList()

你可以使用groupingBy collector:

persons.collect(Collectors.groupingBy(p -> p.getName())).values().forEach(t -> System.out.println(t.get(0).getId()));

如果你想有另一个流,你可以使用这个:

persons.collect(Collectors.groupingBy(p -> p.getName())).values().stream().map(l -> (l.get(0)));

如果你想要名单,下面是最简单的方法

Set<String> set = new HashSet<>(persons.size());
persons.stream().filter(p -> set.add(p.getName())).collect(Collectors.toList());

此外,如果您想要查找不同的或唯一的名称列表,而不是Person,您也可以使用以下两个方法。

方法一:使用区别

persons.stream().map(x->x.getName()).distinct.collect(Collectors.toList());

方法二:使用HashSet

Set<E> set = new HashSet<>();
set.addAll(person.stream().map(x->x.getName()).collect(Collectors.toList()));

你能写的最简单的代码:

    persons.stream().map(x-> x.getName()).distinct().collect(Collectors.toList());

另一个解决方案,使用Set。也许不是理想的解决方案,但有效吗

Set<String> set = new HashSet<>(persons.size());
persons.stream().filter(p -> set.add(p.getName())).collect(Collectors.toList());

或者如果可以修改原始列表,可以使用removeIf方法

persons.removeIf(p -> !set.add(p.getName()));