为了账号安全,请及时绑定邮箱和手机立即绑定

使用方法体的 Java 8 谓词只被调用一次?

使用方法体的 Java 8 谓词只被调用一次?

繁星淼淼 2022-12-15 16:33:52
我检查了以下片段:public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {    Map<Object, Boolean> computed = new ConcurrentHashMap<>();/*IS THIS LINE CALLED ONCE ON STREAM->FILTER NOT MATTER HOW LONG THE STREAM IS*/    return t -> {return computed.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;};}private void test(){    final long d = Stream.of("JOHN","STEPHEN","ORTIZ","RONDON")            .filter(distinctByKey(Function.identity()))            .count();    System.out.println("d = " + d);}这段代码不是我的。我知道在这个例子中使用 aConcurrentMap不是正确的选择,在这种情况下我应该使用ConcurrentMap而不是Map,但这不是我现在关心的问题。我认为distinctByKey在每次迭代中调用或解释该方法Stream。我的意思Map是在每一轮都被实例化,但事实并非如此!方法体Predicate只调用一次吗?在Stream迭代中,这是一个断言吗?因为当我尝试以下代码时:final Function<String,Integer>a = (name)->name.length();System.out.println(distinctByKey(a).test("JOHN"));System.out.println(distinctByKey(a).test("STEPHEN"));System.out.println(distinctByKey(a).test("ORTIZ"));System.out.println(distinctByKey(a).test("RONDON"));我可以看到方法的主体确实在每一行中都被调用了。是什么让过滤器的主体只被调用一次?
查看完整描述

3 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

当您调用.filter(distinctByKey(Function.identity()))时,传递给的参数会filter()被评估。那是唯一一次distinctByKey(Function.identity())执行并返回Predicate<String>.


然后对其进行多次评估(即执行Predicate它的test()方法),每次针对Stream.


为了使您的最后一个代码段的行为类似于Stream管道,它应该如下所示:


final Function<String,Integer> a = (name)->name.length();

Predicate<String> pred = distinctByKey(a);

System.out.println(pred.test("JOHN"));

System.out.println(pred.test("STEPHEN"));

System.out.println(pred.test("ORTIZ"));

System.out.println(pred.test("RONDON"));


查看完整回答
反对 回复 2022-12-15
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

distinctByKey返回缓存 的单个实例。例如,如果将通过 lambda 的创建替换为匿名内部类,则可以获得几乎相同的结果。PredicateConcurrentHashMapPredicate



查看完整回答
反对 回复 2022-12-15
?
慕斯709654

TA贡献1840条经验 获得超5个赞

我认为 distinctByKey 方法在 Stream 的每次迭代中被调用或解释,我的意思是 Map 在每个回合中都是实例,但事实并非如此!我的问题是 Predicate 方法的主体只调用一次?在 Stream 迭代中,这是一个断言吗?


不。Streams 不是魔法,它们不会推翻标准的 Java 语义。考虑提供的代码:


    final long d = Stream.of("JOHN","STEPHEN","ORTIZ","RONDON")

            .filter(distinctByKey(Function.identity()))

            .count();

从图片中取出特定类型和方法,具有以下一般形式:


long x = A.b(y).c(z).d(w);

没有理由期望 、 或 中的任何一个a()在b()该c()链中被多次调用,或者它们的参数每个都被计算多次。这不受某些类型的影响Stream。


相反,在您的情况下,您的方法Predicate返回的(唯一调用)在处理嵌入它的流时被多次使用。它包含对 a 的引用,它在执行其工作时使用和修改它。distinctByKey()PredicateMap


查看完整回答
反对 回复 2022-12-15
  • 3 回答
  • 0 关注
  • 92 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信