为什么要引入lambda表达式
- lambda可以简化代码,lambda 表达式是一个可传递的代码块,可以在以后执行一次或多次。
- 当你想要代码块在以后某个时间点执行,可以使用lambda表达式。
- lambda表达式可以被转换为函数式接口。
- lambda表达式可以在闭包作用域中有效的访问final变量。
- 方法和构造器引用可以引用方法或构造器,但无需调用他们。
Lambda 表达式的基础语法:Java8引入了一个新的操作符“->”,该操作符称为箭头操作符或Lambda操作符。该操作符将Lambda表达式拆分为两个部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda表达式中所需执行的功能,即为Lambda体
() -> System.out.println(“Lambda!”);
语法格式一:无参数,无返回值
此处用Runnable接口举例子,此接口只有一个无参数的run()方法。
public void fun1() {
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("hello,world");
}
};
r.run();
Runnable r1 = () -> System.out.println("接口方法无参数,无返回值");
r1.run();
}
语法格式二:有一个参数(此时小括号可以省略),无返回值
(x) -> System.out.println(x);
x -> System.out.println(x);
接口Consumer,包含方法:void accept(T t);
public void fun2() {
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("接口只有一个参数,无返回值");
}
语法格式三:有多个参数,有返回值,并且Lambda体有多条执行语句。
接口Comparator,包含方法:int compare(T o1, T o2);
public void fun3() {
Comparator<Integer> comparator = (x, y) -> {
System.out.println("x - y = ?");
return Integer.compare(x, y);
};
int compare = comparator.compare(2, 3);
System.out.println(compare);
}
语法格式四:Lambda体只有一条语句,return和花括号都可以省略
。如果花括号省略,return一定要省略
。
public void fun4() {
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
int compare = comparator.compare(2, 3);
System.out.println(compare);
}
语法格式五:Lambda表达式的参数列表的数据类型可以省略不写
,因为JVM编译器可以通过上下文推断出数据类型。
Lambda表达式需要函数式接口的支持。
函数式接口:即接口中只有一个抽象方法的接口。在接口类使用注解@FunctionalInterface
修饰,可以检查是否是函数式接口。
方法引用与构造器引用
如果Lambda表达式的代码块只有一条代码,可以在代码块中使用方法引用和构造器引用。
种类 | 示例 | 说明 | 对应的Lambda表达式 |
---|---|---|---|
引用类方法 | 类名::类方法 | 函数式接口中被实现的全部参数传给该类方法做为参数 | (a,b,…)-> 类名.类方法(a,b,…) |
引用特定对象的实例方法 | 特定对象::实例方法 | 函数式接口中被实现的全部参数传给该类方法做为参数 | (a,b,…)-> 特定对象.实例方法(a,b,…) |
引用某类对象的实例方法 | 类名::实例方法 | 函数接口中被实现的方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数 | (a,b,…)-> a.实例方法(b,…) |
引用构造器 | 类名::new | 函数式接口中被实现方法的全部参数传给该构造器作为参数 | (a,b,…)-> new 类名(a,b,…) |