下面是一个使用数组int[]
而不是int
的代码示例。所有包含i
的行都显示在下面的代码中。此方法由多个线程执行。
int[] i = {0}; //So the stream forEach doesn't complain about a potentially final variable to use...
result.forEach (currentOptionRow -> {
String bgColor = (0 == i[0] % 2) ? "eaeaea" : "ffffff";
//Create HTML, use bgColor to generate alternating background
i[0]++;
});
这是一个变通方法来获得一个可变计数器吗?为什么它是"潜在的最终结果"?(没有final
关键字,为什么要关注?)
这是处理lambda需求所必需的解决方法。lambdas的局部变量必须是final或有效的final。
不,如果你想使用lambda,你不能用int
代替它。
可以修改存储在final int[]
中的元素的值。这就是为什么你可以在lambda内部使用它作为计数器。
实际上lambdas在某种程度上是匿名类,所以当您想要使用局部变量时,必须将该变量声明为final
。
在java 8中,他们添加了effectively final
的概念,这意味着即使没有用final
关键字显式地定义它,它仍然被认为是final
,因为它在代码中只设置了一次。这是为了方便开发人员采用lambda表达式而添加的改进,因为他们不再需要用final
关键字污染他们的代码,他们只需要关注他们的lambda表达式。
所以你确实不能使用int
类型的简单局部变量作为计数器,因为它不能被修改,但你可以使用AtomicInteger
或array
。
如果您使用匿名类而不是lambda,则可以这样做:
result.forEach(new Consumer<String>() {
int i;
@Override
public void accept(final String currentOptionRow) {
String bgColor = (0 == i % 2) ? "eaeaea" : "ffffff";
//Create HTML, use bgColor to generate alternating background
i++;
}
});