Java 8 Distinct by property

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

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

persons.stream().distinct();

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

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

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

 

A1: 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:code

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;
}

Then you can write:ci

persons.stream().filter(distinctByKey(p -> p.getName());

 

A2:  An alternative would be to place the persons in a map using the name as a key:element

persons.collect(toMap(Person::getName, p -> p, (p, q) -> p)).values();

Note that the Person that is kept, in case of a duplicate name, will be the first encontered.rem

相關文章
相關標籤/搜索