Java8新特性 - Lambda表达式
Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码【将代码像数据一样进行传递】。可以写出更加简洁、更加灵活的代码,作为一种跟紧凑的代码风格,是Java的语言表达能力得到提升。
Lambda表达式语法
Java8中引入了一个新的操作符“->”,称为箭头操作符或Lambda操作符。
Lambda操作符将Lambda表达式拆分成两部分
- 左侧:Lambda表达式的参数列表
- 右侧:Lambda表达式中所需要执行的功能,既Lambda体
PS:Java Lambda表达式的一个重要用法是简化某些匿名内部类,所以Lambda表达式的参数列表可以参考为匿名内部类实现接口的方法的参数,Lambda体可以参考为接口实现类的内容。
语法格式一:无参数、无返回值
public class TestLambda {
public static void main(String[] args) {
TestLambdaInterface testLambdaInterface = () -> System.out.println("Lambda Test");
testLambdaInterface.testLambdaFunction();
}
}
interface TestLambdaInterface {
void testLambdaFunction();
}
语法格式二:有参数,无返回值
public class TestLambda {
public static void main(String[] args) {
TestLambdaInterface testLambdaInterface = (x) -> System.out.println(x);
testLambdaInterface.testLambdaFunction("Lambda Test");
}
}
interface TestLambdaInterface {
void testLambdaFunction(String str);
}
PS:
- Lambda表达式的参数列表有多个参数时,用小括号括起来,逗号隔开
- Lambda表达式的参数列表只有一个参数,小括号可以省略
- Lambda表达式的参数列表数据类型可以省略不写,JVM编译器可以通过上下文推断出数据类型【即类型推断】;如果写了的话,就都需要写
语法格式三:有参数,有返回值
public class TestLambda {
public static void main(String[] args) {
TestLambdaInterface testLambdaInterface = (x, y) -> {
if (x > y) {
return x;
}
return y;
};
System.out.println(testLambdaInterface.testLambdaFunction(333, 555));
}
}
interface TestLambdaInterface {
Integer testLambdaFunction(Integer x, Integer y);
}
PS:
- Lambda体有多条语句时,需要用大括号括起来
- Lambda体只有一条语句时,大括号和return都可以省略
函数式接口
只包含一个抽象方法的接口,称为函数式接口。
可以使用@FunctionalInterface注解修饰,用来检查该接口是否是函数式接口。
同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
测试代码
- 新建一个函数式接口
@FunctionalInterface
interface TestLambdaInterface<T> {
String testLambdaFunction(T t);
}
- 作为参数传递Lambda表达式
public static void main(String[] args) {
Demo demo01 = new Demo(3, "哈哈哈");
System.out.println(operation(demo01, (x) -> x.getRemark()));
}
private static String operation(Demo demo, TestLambdaInterface<Demo> testLambdaInterface) {
return testLambdaInterface.testLambdaFunction(demo);
}
class Demo{
Integer num;
String remark;
......
}
PS:
- 为了将Lambda表达式作为参数传递,接收Lambda表达式的参数类型必须是与该Lambda表达式兼容的函数式接口的类型。
- 若Lambda表达式抛出一个异常,那么该异常需要在目标接口的抽象方法上声明。