Lambda表达式
前言
lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
lambda表达式的语法
lambda表达式是一个代码块,以及必须传入代码的变量规范。
lambda表达式的形式:
- (参数列表);
- 箭头:->;
- {表达式};
(String first, String second) -> {
first.length() - second.length();
}
注1:即使参数列表为空,也必须有一个「空括号」。
注2:如果可以推导出一个lambda表达式的参数类型,这编写时可以忽略参数类型的声明。
注3:如果只有一个参数,而且这个参数的类型能推导得出,可以忽略括号。
注4:无须指定lambda表达式的返回类型,返回类型会由上下文推导得出。
警告:如果一个lambda表达式只在某些分支返回一个值,而另外一些分支不返回值,这是不合法的!
函数式接口
对于「只有」一个「抽象」方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式,这种接口称为函数式接口。
lambda表达式可以转换为一个函数式接口。
Arrays.sort(stringList,(first,second) -> {
first.length() - second.length();
});
在java.util.function包中定义了很多非常通用的函数式接口。
注:lambda表达式不能赋给一个对象,只能转换为函数式接口。
如果需要设计自己的函数式接口,可以使用「@FunctionalInterface注解」来标记这个接口,优点有两个:
- javadoc页里会指出你的接口时一个函数式接口;
- 如果不小心增加了另外一个抽象方法,编译器会产生一个错误消息;
方法引用
表达式System.out::println是一个方法引用,它指示编译器生成一个函数式接口的实例,「覆盖」这个接口的抽象方法来调用给定的方法。
var timer = new Timer(1000,System.out::println);
方法引用的语法:
- 对象名或类名;
- 分隔符「::」;
- 方法名;
方法引用 | 解释 |
---|---|
object::instanceMethod | 等价于:object -> instanceMethod(object) |
Class::instanceMethod | 等价于:(x,y) -> x.instanceMethod(y) |
Class::staticMethod | 等价于:(x,y) -> ClassName.staticMethod(x,y) |
注1:只有当lambda表达式的方法体「只调用了一个方法而不做其他操作」时,才能把lambda表达式重写为方法引用。
注2:如果有多个同名的重载方法,编译器回尝试从上下文中找到你指的是哪一个方法。
构造器引用
构造器引用与方法引用类似,只不过方法名为「new」。
ArrayList<String> stringList = new ArrayList(2);
stringList.add("1");
stringList.add("2");
// Persion(String)
stringList.stream().map(Person::new)
如果存在多个构造器方法,编译器会根据上下文选择合适的构造器方法调用。
可以用数组类型建立构造器引用。
// 数组构造器引用,它有一个参数作为数组的长度,等价于lambda表达式:x->new int[x]
int[]::new
Java有一个限制,无法构造泛型类型T的数组,数组构造器引用对于克服这个限制很有用。可以通过传入一个数组构造器引用,通过调用这个构造器来得到正确类型的数组。
注:表达式new T[n]会产生错误,因为这会改为new Object[n]。
// 不使用数组构造器引用
Object[] personArray = steam.toArray();
// 使用数组构造器引用
Person[] personArray = steam.toArray(Person[]::new);
变量作用域
lambda表达式可以捕获外围作用域中变量的值,但是只能引用「值不会改变的变量」。
注1:如果在lambda表达式中更改变量,这是不合法的,因为并发执行多个动作时就会不安全。
注2:如果在lambda表达式中引用一个变量,而这个变量可能在外部发生改变,也是不合法的。
注3:lambda表达式中捕获(引用)的变量必须实际上是事实最终变量(等价于final关键字修饰)。
在一个lambda表达式中使用this关键字时,this指的是创建这个lambda表达的方法所在的对象。
标签:接口,引用,new,Lambda,方法,表达式,lambda From: https://www.cnblogs.com/myblog20231005/p/17749109.html