Doz*_*Doz 3 java arrays lambda interface functional-interface
public class ArraysDemo {
public static void main(String[] args) {
int[] a = {0, 2, 4, 6, 8};
int[] b = {10, 12, 14, 16, 18};
Arrays.setAll(a, i -> b[i]+1);
System.out.println(Arrays.toString(a));
}
}
Run Code Online (Sandbox Code Playgroud)
输出: [11, 13, 15, 17, 19]
setAll()使用的函数的来源如下:
public static void setAll(int[] array, IntUnaryOperator generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.applyAsInt(i);
}
Run Code Online (Sandbox Code Playgroud)
IntUnaryOperator 是一个功能界面,这是其来源的一部分:
public interface IntUnaryOperator {
int applyAsInt(int operand);
// rest methods are omitted
}
Run Code Online (Sandbox Code Playgroud)
如果我错了,请纠正我,但我对Java中lambda表达式的理解是,当我将lambda表达式作为参数传递给setAll()方法时,IntUnaryOperator创建并调用实现接口的匿名类的对象generator.lambda表达式本质上是该applyAsInt()方法的一个实现,所以我相信它会转化为:
int applyAsInt(int operand){
return b[operand]+1;
}
Run Code Online (Sandbox Code Playgroud)
我有意义的是它可以访问,operand因为它作为参数传递array[i] = generator.applyAsInt(i);但是,我不知道它可以如何操作b- 它不作为参数传递,所以如何可以引用它?我错过了什么?
原因是它b实际上是最终的.
可以在lambda的主体中使用和更改实例和静态变量而不受限制.然而,局部变量的使用受到更多限制:除非它们实际上是最终的,否则不允许捕获局部变量,这是Java 8中引入的概念.非正式地,如果局部变量的初始值从未改变(包括内部变量),则局部变量实际上是最终的. lambda表达式的主体) - 换句话说,声明最终不会导致编译失败.有效终结的概念并没有向Java引入任何新的语义; 它只是一种稍微简单的定义最终变量的方式.
来自http://www.lambdafaq.org/can-lambda-expressions-use-variables-from-their-environment/