下面的for循环生成lambda表达式的集合。
Callable<String>[] tasks = new Callable[messageCount];
for (int i = 0; i < count; i++) {
tasks[i] = () -> msg;
}
对流forEach进行相同的尝试会产生空值。
Arrays.stream(tasks).forEach(t -> {
t = () -> message;
});
我想念什么?我该如何解决?
答案 0 :(得分:2)
在第一个代码示例中,您正在将lambda表达式() -> msg
分配给tasks
数组的每个元素。
但是,在第二个示例中,您正在将lambda表达式() -> msg
分配给类型为t
的临时变量Callable<String>
。 Stream#forEach
的目的是将流中的元素传递给以某种方式使用元素的消费者。如果您以某种方式分配给使用者的参数,则流的源将不会反映出来。这样的操作甚至可能没有任何意义:
IntStream.range(1,10).filter((x) -> (x % 2 == 0)).forEach((x) -> {++x;});
这与Java流的一般主题有关:它们是用于生成,转换,过滤和使用数据的单向管道。由于数据从Arrays.stream
供应商处流动,因此只能沿一个方向流入消费者(forEach
);下游所做的更改不会传播回上游。
答案 1 :(得分:0)
您的流代码等效于以下for
循环:
for (Callable<String> t : tasks) {
t = () -> message;
}
其本身等同于:
for (int i = 0; i < tasks.length; i++) {
Callable<String> t = tasks[i];
t = () -> msg;
}
更改t
的值不会更改tasks[i]
的值。
要创建长度为messageCount
且元素为lambda表达式的数组,请使用流式传输:
Callable<String>[] tasks = IntStream.range(0, messageCount)
.mapToObj(i -> (Callable<String>) () -> msg)
.toArray(Callable[]::new);