在Java 8中,如何Stream通过检查每个对象的属性的不同性来使用API 过滤集合?
Stream
例如,我有一个Person对象列表,我想删除同名的人,
Person
persons.stream().distinct();
将对对象使用默认的相等性检查Person,所以我需要类似的东西,
persons.stream().distinct(p -> p.getName());
不幸的是,该distinct()方法没有这种过载。如果不修改Person类内部的相等性检查,是否可以简洁地做到这一点?
distinct()
考虑distinct做一个有状态过滤器。这是一个函数,该函数返回一个谓词,该谓词保持先前状态的状态,并返回是否第一次看到给定元素:
distinct
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()。