谓词如何在Java 8中维护状态 [英] How Predicate maintain state in Java 8
问题描述
我正在查看此代码,并试图理解以下代码.
I am looking at this code and trying to understand the following piece of code.
public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
BigDecimal totalShare = orders.stream()
.filter(distinctByKey(o -> o.getCompany().getId()))
.map(Order::getShare)
.reduce(BigDecimal.ZERO, BigDecimal::add);
我的问题是每次调用 distinctByKey 并生成新的 ConcurrentHashMap .使用 new ConcurrentHashMap<>(); 吗?
My question here is everytime distinctByKey will be called and resulting new ConcurrentHashMap. how it is maintaining the state using new ConcurrentHashMap<>(); ?
推荐答案
由于这是一个捕获的lambda,实际上,每次调用 distinctByKey时,都会一直返回一个新的
;但这会在整个流中发生,而不是在每个单独的元素中发生. Predicate
实例.
Since this is a capturing lambda, indeed a new Predicate
instance will be returned all the time on each call to distinctByKey
; but this will happen per entire stream, not per each individual element.
如果您愿意使用以下示例运行示例
If you are willing to run your example with:
Djdk.internal.lambda.dumpProxyClasses =/您的/路径/此处
您会看到为 Predicate
的实现生成了 class
.由于这是一个有状态的lambda-它捕获 CHM
和 Function
,因此它将具有 private
构造函数和静态工厂方法
返回实例.
you would see that a class
is generated for your the implementation of the Predicate
. Because this is a stateful lambda - it captures the CHM
and Function
, it will have a private
constructor and a static factory method
that returns an instance.
每次对 distinctByKey
的调用都会产生一个不同的实例,但是该实例将被重用于Stream的每个元素.如果运行此示例,事情可能会更加明显:
Each call of distinctByKey
will produce a different instance, but that instance will be reused for each element of the Stream. Things might be a bit more obvious if you run this example:
public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
Predicate<T> predicate = t -> {
Object obj = keyExtractor.apply(t);
System.out.println("stream element : " + obj);
return seen.putIfAbsent(obj, Boolean.TRUE) == null;
};
System.out.println("Predicate with hash :" + predicate.hashCode());
return predicate;
}
@Getter
@AllArgsConstructor
static class User {
private final String name;
}
public static void main(String[] args) {
Stream.of(new User("a"), new User("b"))
.filter(distinctByKey(User::getName))
.collect(Collectors.toList());
}
这将输出:
Predicate with hash :1259475182
stream element : a
stream element : b
流的两个元素的单个谓词
.
如果添加另一个过滤器
:
Stream.of(new User("a"), new User("b"))
.filter(distinctByKey(User::getName))
.filter(distinctByKey(User::getName))
.collect(Collectors.toList());
会有两个谓词
:
Predicate with hash :1259475182
Predicate with hash :1072591677
stream element : a
stream element : a
stream element : b
stream element : b
这篇关于谓词如何在Java 8中维护状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!