在 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()。