我看不出这有什么大的区别:
List<CompletableFuture<Integer>> intFutures = Stream.of(1, 2, 3, 4)
.map(input -> CompletableFuture.supplyAsync(() -> computeSomethingLong(input)))
.map(future -> future.thenApply(input -> input * 2))
.map(future -> future.thenCompose(computed -> CompletableFuture.supplyAsync(() -> computeSomethingLong(computed))))
.collect(toList());还有这个:
List<CompletableFuture<Integer>> intFutures = Stream.of(1, 2, 3, 4)
.map(input -> CompletableFuture.supplyAsync(() -> computeSomethingLong(input))
.thenApply(computed -> computed * 2)
.thenCompose(computed -> CompletableFuture.supplyAsync(() -> computeSomethingLong(computed))))
.collect(toList());我做了一个测试,结果和执行时间是一样的。我能看到的唯一区别是,第二个提议允许沿着链访问input变量。因此,如果我稍后在另一个任务中需要它,我可以使用它。
我说错了吗?还有其他不同之处吗?
发布于 2021-04-17 15:26:33
你的结论是正确的。这(几乎)没有区别-多次调用map可能会分配更多的内存,因为需要创建和返回一个新的流实例。在语义上,这两种形式是等价的,并产生相同的结果。
如果您需要访问输入的初始值,那么您需要将操作组合到单个操作中;否则,变量在操作(即lambda)的作用域中不可用。
更一般地说:
stream
.map(x -> operation1(x))
.map(x -> operation2(x))
.map(x -> operation3(x))
.toList();
// is equivalent to:
stream
.map(x -> operation3(operation2(operation1(x))))
.toList();或者使用方法调用:
stream
.map(x -> x.method1())
.map(x -> x.method2())
.map(x -> x.method3())
.toList();
// equivalent to:
stream
.map(x -> x.method1().method2().method3())
.toList();https://stackoverflow.com/questions/67135516
复制相似问题