Lambda表达式——一种紧凑的,传递行为的方式。
先看这样一段代码
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("button clicked");
}
});
以上代码是将一个Listener对象作为匿名内部类传入方法中,传递的是对象;
而我们只想传入一个行为,这种 情况就可以写成一个Lambda表达式: 使用Lambda表达式将行为和按钮单击进行关联
button.addActionListener(event -> System.out.println("button clicked"));
这里我们传入的不是一个对象,而是一段代码——一个没有名字的函数。
event是参数名,也就是上面的ActionEvent event
->将参数名和代码主体(一段代码)分开
不同之处:
匿名内部类,需要声明event的参数类型;Lambda中无需指定类型,就可以编译。
原理:javac在使用Lambda表达式的时候,会根据方法签名addActionListener在后台推断出event的类型。像这样参数类型可以推断的,就不用显示指定。
Runnable noArguments = () -> System.out.println("Hello World");
()表示没有参数;实现了Runnable接口,该接口也只有一个run方法,无参返回void
ActionListener oneArgument = event -> System.out.println("button clicked");
只包含一个参数,可省略参数的括号
Runnable multiStatement = () -> {
System.out.print("Hello");
System.out.println(" World");
};
Lambda 表达式的主体不仅可以是一个表达式,而且也可以是一段代码块,使用大括号({})将代码块括起来
和普通代码一样,可以返回或跑出异常来退出; 只有一行代码的时候也可以用{}
BinaryOperator<Long> add = (x, y) -> x + y;
可以表示包含多个参数的方法;这行代码并不是将两个数字相加,而是创建了一个用来计算两个参数相加的函数;
类型是BinaryOperator<Long>指的不是两个数字相加的值,而是把两个数字相加的那行代码
BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;
上面说到javac可以推断得出参数类型, 但是有时候还是显示声明的好,需要用小括号括起来,比如上面的(Long x, Long y)
目标类型是指Lambda 表达式所在上下文环境的类型。比如,将Lambda 表
达式赋值给一个局部变量,或传递给一个方法作为参数,局部变量或方法参
数的类型就是Lambda 表达式的目标类型。
目标类型其实早有接触,例如,Java中初始化数组的时候,数组的类型就是根据上下文推断出来的,例如
String[] array = { "hello", "world" }
右边的代码并没有声明类型,是根据前面的类型推断出来的。