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

我检查了以下片段:


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"));

我可以看到方法的主体确实在每一行中都被调用了。是什么让过滤器的主体只被调用一次?


繁星淼淼
浏览 95回答 3
3回答

RISEBY

当您调用.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"));

慕田峪4524236

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

慕斯709654

我认为 distinctByKey 方法在 Stream 的每次迭代中被调用或解释,我的意思是 Map 在每个回合中都是实例,但事实并非如此!我的问题是 Predicate 方法的主体只调用一次?在 Stream 迭代中,这是一个断言吗?不。Streams 不是魔法,它们不会推翻标准的 Java 语义。考虑提供的代码:&nbsp; &nbsp; final long d = Stream.of("JOHN","STEPHEN","ORTIZ","RONDON")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(distinctByKey(Function.identity()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .count();从图片中取出特定类型和方法,具有以下一般形式:long x = A.b(y).c(z).d(w);没有理由期望 、 或 中的任何一个a()在b()该c()链中被多次调用,或者它们的参数每个都被计算多次。这不受某些类型的影响Stream。相反,在您的情况下,您的方法Predicate返回的(唯一调用)在处理嵌入它的流时被多次使用。它包含对 a 的引用,它在执行其工作时使用和修改它。distinctByKey()PredicateMap
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java