Java SE 8 中的lambda表达式

  |   0 评论   |   0 浏览

Lambda表达式是什么

Lambda 表达式(lambda expression)是一个匿名函数,即没有函数名的函数。

使用Lambda表达式可以对匿名类进行简化
比如在对集合中的元素进行排序时,通常需要向sort()方法中传入一个比较器。在Java 8之前,通常我们会声明并初始化一个匿名类:

1Collections.sort(words, new Comparator<String>() {
2    @Override
3    public int compare(String o1, String o2) {
4        return Integer.compare(o1.length(), o2.length());
5    }
6});

不难发现,真正有用的部分其实是匿名类中方法的算法逻辑。Java 8提供了lambda表达式来简化代码,使用lambda表达式表示匿名类中方法的算法逻辑:

1Collections.sort(words,
2                 (s1,s2)->Integer.compare(s1.length(), s2.length()));

lambda表达式把接口名和函数名一并省掉了,这样看起来更加简洁。

但是,并不是所有的匿名类都可以使用lambda表达式代替,lambda表达式必须有相应的函数式接口(functional interface)。

函数式接口也是Java 8引入的一个概念,函数式接口的特点:它只能有一个抽象方法(不包括来自Object的方法)。
Java 8新增的java.util.function包中提供了一些通用的函数式接口。
当然,我们也可以自定义函数式接口,只需要编写一个只有一个抽象方法的接口即可:

1@FunctionalInterface
2public interface ConsumerInterface<T>{
3    void accept(T t);
4}
5// 代码中的@FunctionalInterface是可选的,但加上该注解编译器会帮我们检查接口是否符合函数接口规范。

lambda表达式的语法

lambda表达式包含三个部分:

  • 括号及包含在括号内的参数列表(若无参数括号也不能省略)
  • 箭头(->)
  • 方法体(表达式或者语句块)

示例

 1// 若方法体是语句块,需将语句放到{}中
 2(String first, String second)->{
 3    if (first.length() < second.length()) return -1;
 4    else if(first.length() > second.length()) return 1;
 5    else return 0;
 6}
 7// 无参数时,括号不能省略
 8()->{for(int i = 100; i>=0; i--){
 9    System.out.println(i);
10}}
11// 若能推导出参数类型,则参数类型可以省略
12Comparator<String> comp =
13        (first, second) -> first.length() - second.length();
14// 若只有一个参数,并且参数类型可以推导得出,则可以省略括号
15ActionListener listener =
16        event -> System.out.println("The time is " + new Date());

方法引用

假如一个lambda表达式仅仅是调用了一个已经存在的方法,那么lambda表达式还可以被简化为方法引用

示例

1Timer timer = new Timer(1000, e-> System.out.println(e));

上面代码中的lambda表达式可以改写成下面的形式:

1Timer timer = new Timer(1000, System.out::println);

方法引用省略了参数,这样更加简单明了。

方法引用的分类

类型 示例
Reference to a static method ContainingClass::staticMethodName
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName
Reference to a constructor ClassName::new

相关资料

Lambda Expressions
9.8. Functional Interfaces
Method References
https://objcoding.com/2019/03/04/lambda/#lambda-and-collections