Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用方法体的Java8谓词只调用一次?_Java_Java 8_Predicate - Fatal编程技术网

使用方法体的Java8谓词只调用一次?

使用方法体的Java8谓词只调用一次?,java,java-8,predicate,Java,Java 8,Predicate,我已经检查了以下代码片段: 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 H

我已经检查了以下代码片段:

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

我可以看到,方法的主体确实在每一行中都被调用。是什么使筛选器主体只被调用一次?

distinctByKey
返回缓存
ConcurrentHashMap
谓词的单个实例。例如,如果通过lambda将
谓词的创建替换为匿名内部类,则可以实现几乎相同的效果。

当调用
.filter(distinctByKey(Function.identity())
时,将计算传递给
filter()
的参数。这是执行
distinctByKey(Function.identity())
并返回
谓词的实例的唯一时间

然后对
谓词
进行多次评估(即执行
test()
方法),每次都针对
的不同元素

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

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"));
final函数a=(name)->name.length();
谓词pred=distinctByKey(a);
系统输出打印(预测试(“约翰”);
系统输出打印(预测试(“STEPHEN”);
系统输出打印(预测试(“ORTIZ”);
系统输出打印(预测试(“RONDON”);
我认为distinctByKey方法是在中调用或解释的 流的每次迭代我指的是每个 转身,但它不是!我的问题是谓词方法的主体 只打一次电话?在流迭代中,这是一个断言吗

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

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

long x = A.b(y).c(z).d(w);
没有理由期望
a()
b()
c()
中的任何一个在该链中被调用不止一次,或者它们的参数被评估不止一次。这不受
流的某些类型的影响


相反,在您的情况下,由
distinctByKey()
方法(唯一调用)返回的
谓词在处理嵌入它的流时被多次使用。该
谓词
包含对
映射的引用,它在执行其工作时使用并修改该映射。

我认为您的代码是从中获取的,在阅读他的另一个映射时,它可能会被清除
distinctByKey()
只调用一次。但是它返回的谓词被称为每一个元素。嘿,伙计,我发现我正在工作的这个项目的代码可能是被复制的并且诚实地:考虑围绕这个主题重写你的问题。比如:让
test()
方法打印一些东西有什么意义。。。打印出来的东西到处都看不见。更糟糕的是:使用名为test的方法。。。如果您同时调用谓词
test()
方法,那么哪种方法会让您感到困惑呢?您说“我知道在本例中使用
ConcurrentMap
不是正确的选择,我应该使用
ConcurrentMap
…”是什么意思?这没有任何意义。除此之外,
t->{return computed.putIfAbsent(keyExtractor.apply(t),Boolean.TRUE)==null;}
是不必要的复杂。您只需编写
t->computed.putIfAbsent(keydextractor.apply(t),Boolean.TRUE)==null
。是的,我认为它就是这样工作的。但我面对这个片段,我说地图是每个转弯的实例,但我错了。
    final long d = Stream.of("JOHN","STEPHEN","ORTIZ","RONDON")
            .filter(distinctByKey(Function.identity()))
            .count();
long x = A.b(y).c(z).d(w);