Java 8 个使用方法体的谓词只被调用一次?
Java 8 predicates using methods bodies are called only once?
我检查了以下片段:
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);
}
这个代码不是我的。我知道在这个例子中使用 ConcurrentMap
不是正确的选择,在这种情况下我应该使用 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"));
我可以看到方法的主体确实在每一行中都被调用了。是什么让过滤器的主体只被调用一次?
distinctByKey
returns 缓存 ConcurrentHashMap
的 Predicate
的 单个 实例。例如,如果您通过 lambda 将 Predicate
的创建替换为匿名内部 class,则您可以获得几乎相同的结果。
当您调用 .filter(distinctByKey(Function.identity()))
时,将评估传递给 filter()
的参数。那是唯一一次 distinctByKey(Function.identity())
被执行并且 returns 是 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"));
I thought that the distinctByKey method is called or interpreted in
each iteration of the Stream i mean the Map being instance in each
turn but it's not! my question is the body of the Predicate method
call only one time? in the Stream iteration is this a assertion?
没有。流不是魔法,它们不会推翻标准 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
.
的影响
在您的情况下发生的情况是,您的 distinctByKey()
方法(唯一调用)返回的 Predicate
不止一次被 使用 作为处理嵌入它的流。 Predicate
包含对 Map
的引用,它在执行其工作时使用和修改它。
我检查了以下片段:
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);
}
这个代码不是我的。我知道在这个例子中使用 ConcurrentMap
不是正确的选择,在这种情况下我应该使用 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"));
我可以看到方法的主体确实在每一行中都被调用了。是什么让过滤器的主体只被调用一次?
distinctByKey
returns 缓存 ConcurrentHashMap
的 Predicate
的 单个 实例。例如,如果您通过 lambda 将 Predicate
的创建替换为匿名内部 class,则您可以获得几乎相同的结果。
当您调用 .filter(distinctByKey(Function.identity()))
时,将评估传递给 filter()
的参数。那是唯一一次 distinctByKey(Function.identity())
被执行并且 returns 是 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"));
I thought that the distinctByKey method is called or interpreted in each iteration of the Stream i mean the Map being instance in each turn but it's not! my question is the body of the Predicate method call only one time? in the Stream iteration is this a assertion?
没有。流不是魔法,它们不会推翻标准 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
.
在您的情况下发生的情况是,您的 distinctByKey()
方法(唯一调用)返回的 Predicate
不止一次被 使用 作为处理嵌入它的流。 Predicate
包含对 Map
的引用,它在执行其工作时使用和修改它。