Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.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
在streams中使用Java8实现延迟评估_Java_Java 8_Java Stream_Lazy Evaluation - Fatal编程技术网

在streams中使用Java8实现延迟评估

在streams中使用Java8实现延迟评估,java,java-8,java-stream,lazy-evaluation,Java,Java 8,Java Stream,Lazy Evaluation,我试图在这样的流中使用供应商来实现惰性评估 public static void main(String[] args) { Supplier<List<String>> expensiveListSupplier= getExpensiveList(); getList().stream() .filter(s -> expensiveListSupplier.get().contains(s))

我试图在这样的流中使用供应商来实现惰性评估

public static void main(String[] args) {

        Supplier<List<String>> expensiveListSupplier= getExpensiveList();
        getList().stream()
                .filter(s -> expensiveListSupplier.get().contains(s))
                .forEach(System.out::println);
    }

    private static Supplier<List<String>> getExpensiveList() {
        return () -> Stream
                .of("1", "2", "3")
                .peek(System.out::println)
                .collect(Collectors.toList());
    }

    private static List<String> getList() {
        return Stream.of("2", "3")
                .collect(Collectors.toList());
    }
publicstaticvoidmain(字符串[]args){
供应商费用清单Supplier=getExpensiveList();
getList().stream()
.filter->expensiveListSupplier.get().contains)
.forEach(System.out::println);
}
私有静态供应商getExpensiveList(){
return()->Stream
。of(“1”、“2”、“3”)
.peek(System.out::println)
.collect(Collectors.toList());
}
私有静态列表getList(){
返回流。共(“2”、“3”)
.collect(Collectors.toList());
}
但这将为列表中的每个元素调用getExpensiveList()方法。 我尽量不冗长,也不想写像这样的东西来添加非空支票和东西

public static void main(String[] args) {

        Supplier<List<String>> expensiveListSupplier = getExpensiveList();
        List<String> list = getList();
        if (!list.isEmpty()) {
            List<String> expensiveList = expensiveListSupplier.get();
            list.stream()
                    .filter(expensiveList::contains)
                    .forEach(System.out::println);
        }    
    }

    private static Supplier<List<String>> getExpensiveList() {
        return () -> Stream
                .of("1", "2", "3")
                .peek(System.out::println)
                .collect(Collectors.toList());
    }

    private static List<String> getList() {
        return Stream.of("2", "3")
                .collect(Collectors.toList());
    }
publicstaticvoidmain(字符串[]args){
供应商费用清单Supplier=getExpensiveList();
List=getList();
如果(!list.isEmpty()){
List expensiveList=expensiveListSupplier.get();
list.stream()
.filter(费用列表::包含)
.forEach(System.out::println);
}    
}
私有静态供应商getExpensiveList(){
return()->Stream
。of(“1”、“2”、“3”)
.peek(System.out::println)
.collect(Collectors.toList());
}
私有静态列表getList(){
返回流。共(“2”、“3”)
.collect(Collectors.toList());
}

我认为仅使用标准Java类不可能做到这一点。但您可以编写自己的惰性计算器并使用它,例如(未经测试):

公共类LazyValue实现供应商{
私人T值;
私人最终供应商初始签字人;
公共懒散值(供应商初始值设定项){
this.initializer=初始值设定项;
} 
公共部门得不到{
如果(值==null){
value=initializer.get();
}
返回值;
}
}
还有其他可能性,例如,请参见

但要当心!如果您添加了延迟计算,那么您就有了一个可变的数据结构,所以如果您在多线程环境(或并行流)中使用它,那么就添加同步


但是,我会使用你的详细版本。它的作用很明显,只长了四行。(在实际代码中,我希望这四行是不相关的。)

第二个变体可以简化为

List<String> list = getList();
if(!list.isEmpty()) {
    list.stream()
        .filter(getExpensiveList().get()::contains)
        .forEach(System.out::println);
}

相反,要避免重复的线性搜索。或者重新设计
getExpensiveList()
以首先返回一个
Set

您的问题是什么?你能简化一下吗。。我尽量不冗长,也不想写这样的东西来添加非空的检查和东西?你可以调用
Set expensiveStuff=new HashSet(getExpensiveList().get())。使用集合可以在恒定的运行时间内扩展到任何实际大小。一个小提示:供应商实例在被使用后,可以防止垃圾收集,并且为了并行执行流,您可以检查此链接,因为@Hoopje指出,更适合您的详细代码。这里使用
supplier
有什么意义?您需要已经获得第一个元素的列表,因此与代码的复杂性相比,惰性是很小的。我想是这样的!!。我只是想看看是否有人想出了一个简洁实用的解决方案。添加第二个代码段的原因是为了解释我的问题(第一个代码段),而不是为了改进它。我认为你的回答并没有增加我想要问的问题的价值。无论如何,感谢您的回答。对于流的每个元素,这不是调用了
getExpensiveList().get()
。@Amardeep我决定提供第二个代码片段的改进版本,因为它在您的问题中看起来更复杂,而实际上比第一个版本更简单。正如我在回答中已经解释的那样,您的第一个变体没有提供任何实际好处,即关于期望的惰性。因此,有一种变体更简单,但与其他变体相比仍然没有任何缺点。如果这不是答案,您可能问错了问题。@Federicoperaltachaffner否,
expression::name
表单的方法引用将对表达式求值一次并捕获结果。另见…@Federicoperaltachaffner是的,正如我在问题中指出的那样。最重要的是,这就是提出这个问题的原因。
List<String> list = getList();
if(!list.isEmpty()) {
    list.stream()
        .filter(getExpensiveList().get()::contains)
        .forEach(System.out::println);
}
List<String> list = getList();
if(!list.isEmpty()) {
    list.stream()
        .filter(new HashSet<>(getExpensiveList().get())::contains)
        .forEach(System.out::println);
}