最开始只是拿来用,后来调试研究了一下。
解释:2 传递的是对象,对象中包含 keySet 变量,每次调用都是这个对象里面的 keySet 变量。
而 1 每次都是创建了一个新的对象,keySet 自然不同,也就不能实现过滤了
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
class Scratch {
public static void main(String[] args) {
Stream.generate(() -> 1)
.limit(25)
// .distinct()
.filter(i -> {
ConcurrentHashMap.KeySetView<Object, Boolean> keySet = ConcurrentHashMap.newKeySet();
return keySet.add(i);
})// 1. 此处过滤无用
.filter(distinctByKey(Function.identity()))// 2. 此处过滤有用,原因就是两个 keySet 变量的作用域与生命周期不同
.forEach(System.out::println);
// 解释:2 传递的是对象,对象中包含 keySet 变量,每次调用都是这个对象里面的 keySet 变量。
// 而 1 每次都是创建了一个新的对象,keySet 自然不同,也就不能实现过滤了
System.out.println(distinctByKey(t -> 1));
}
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
ConcurrentHashMap.KeySetView<Object, Boolean> keySet = ConcurrentHashMap.newKeySet();
return t -> keySet.add(keyExtractor.apply(t));
}
}