一、lambda表达式
-
Lambda表达式介绍:
是一种紧凑的、传递行为的方式。Lambda表达式是一个匿名函数,可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递),使Lambda表达式可以写出更简洁、更灵活的代码。 -
Lambda表达式的格式:(o1,o2)->Integer.compare(o1,o2)
-> :Lambda操作符 或 箭头操作符
->左边 :Lambda形参列表(接口中的抽象方法的形参列表)
->右边 :Lambda体(重写的抽象方法的方法体) -
编写 Lambda 表达式的不同形式
(1)无参,无返回值
Runnable noArguments = () -> System.out.println("Hello World");
(2)需要一个参数,但是没有返回值
Consumer<String> con2 = (String s)->{
System.out.println(s);
};
数据类型可以省略,因为可由编译器推断得出,称为"类型推断"
Consumer<String> con2 = (s) -> {
System.out.println(s);
};
若只需要一个参数时,参数得小括号可以省略:
Consumer<String> con2 = s -> {
System.out.println(s);
};
(3)需要两个或以上的参数,多条执行语句,并且可以有返回值
Comparator<Integer> com = (o1,o2)->{
System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
};
(4)Lambda体只有一条语句时,return与大括号若有,都可以省略
Comparator<Integer> com = (o1,o2)- > o1.compareTo(o2);
- Lambda表达式引用值,而不是变量
使用匿名内部类,如果需要引用它所在方法里面的变量,这时,需要将变量声明为final。
匿名内部类中使用 final 局部变量:
final String name = getUserName();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("hi " + name);
}
});
Java8虽然无需将变量声明为final,但是在Lambda表达式中,也无法用作非终态变量。
使用既成事实上的 final 变量,导致无法通过编译:
String name = getUserName();
name = formatUserName(name);
button.addActionListener(event -> System.out.println("hi " + name));
试图给该变量多次赋值,然后在 Lambda 表达式中引用它,编译器就会报错。
也就是说,Lambda 表达式中引用的局部变量必须是 final 或既成事实上的 final 变量。
- 总结:
->左边:lambda形参列表的参数类型可以省略;如果形参列表只有一个参数,可以省略括号。
->右边:如果lambda体只有一条执行语句,可以省略一对{}和return语句。
二、函数式接口
- Lambda表达式需要函数式接口的支持
函数式接口:接口中只有一个抽象方法的接口成为函数式接口。可以使用@FunctionalInterface注解修饰,@FunctionalInterface 注解可以检查接口是否为函数式接口 - 四大核心函数式接口
Consumer<T> :消费型接口:对类型为T的对象应用操作
void accept(T t);
Supplier<T> : 供给型接口:返回类型为T的对象
T get();
Function<T,R> : 函数型接口:对类型为T的对象应用操作并返回结果。结果是R类型的对象
R apply(T t);
Predicate<T> : 断言型接口:确定类型为T的对象是否满足某约束,并返回boolean值
boolean test(T t);
三、方法引用
方法引用:
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。方法引用可以看作是Lambda表达式深层次的表达。换句话说,
方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
格式:
使用操作符"::"将类或对象与方法名分割开来
如下三种主要使用情况:
对象::实例方法名
类::静态方法名
类::实例方法名
方法引用的使用情境:当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用!
方法引用,本质上就是lambda表达式,而lambda表达式作为函数式接口的实例。所以方法引用也是函数式接口的实例。
构造器引用:
Supplier<Employee> sup1 = () -> new Employee();
Supplier<Employee> sup1 = Employee::new
网友评论