Lambda表达式

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表达的方法所在的对象。

posted @   Ohana+  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示