【发布时间】:2016-04-12 01:57:02
【问题描述】:
代码:
int counter = 0;
int[] counterInArray = {1};
IntStream.range(1, 100)//couldn't compile since counter is not effectively final
.forEach(x -> System.out.println(x + ": " + counter++));
IntStream.range(1, 100)//Works well
.forEach(x -> System.out.println(x + ": " + counterInArray[0]++));
IntStream.range(1, 100).parallel()//parallel breaks the counter, so we should be careful
.forEach(x -> System.out.println(x + ": " + counterInArray[0]++));
如您所见,我们可以做一个简单的 hack(将其放入数组中)以使变量有效地最终化并在单线程情况下运行良好。
那么,为什么在 Java lambda 表达式中将变量限制为有效的 final 呢?
当我们想要使用一些不是有效最终但它适用于单线程流的变量时,我们必须破解它。
您可以阅读我的post,了解如何在 lambda 中找到破解计数器的好方法(当然,这不是有效的 final)。
【问题讨论】:
-
这看起来很实用,但它违背了函数式编程的要点:避免状态更改。此外:如果您需要(线程安全)计数器,请使用计数器,而不是 int。计数器可以是
final。