Java Lambda 表达式

Yuan Shen 原神 Screenshot 2024.08.08 - 20.04.26.71

Lambda 表达式是Java 8中引入的特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。也就是函数式编程。Java 8以前想要把某些功能传递给某些方法,总要去写匿名类,这里先来了解学习一下匿名类。

匿名类

在Java中,一个类可以包含另一个称为嵌套类的类。可以在不提供任何名称的情况下创建嵌套类。

没有任何名称的嵌套类称为匿名类。

例如下面这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package lambda;

import java.util.Arrays;
import java.util.Comparator;
public class Old {
public static void main(String[] args) {
String[] oldWay = "Improving code with Lambda expressions in Java 8".split(" ");
/* Arrays.sort 是一个用于排序数组的方法。它接受两个参数:

要排序的数组(oldWay)。
一个比较器(Comparator<String>),用来定义排序的逻辑。*/
Arrays.sort(oldWay, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.toLowerCase().compareTo(s2.toLowerCase());
}
});
System.out.println(String.join(", ",oldWay));
}
}

匿名类通常继承子类或实现接口。

在这里,**类型(Type)**可以是

  1. 匿名类继承的超类
  2. 匿名类实现的接口

示例中new Comparator<String>() 创建了一个匿名内部类,它实现了 Comparator<String> 接口。

Lambda表达式

只有一个抽象方法的接口非常特殊,值得特殊对待。

在仅使用一次方法的地方特别有用,方法定义很短。它为我们节省了,如包含类声明和编写单独方法的工作。

示例在java 8 中可以简化为

1
2
3
4
5
6
7
8
9
10
11
12
13
package lambda;

import java.util.Arrays;

public class New {
public static void main(String[] args){
String[] newWay = "Improving code with Lambda expressions in Java 8".split(" ");
Arrays.sort(newWay,(s1,s2) -> {
return s1.toLowerCase().compareTo(s2.toLowerCase());
});
System.out.println(String.join(",",newWay));
}
}

(argument)->{body}来表示lambda。样板代码不见了就更加简洁。

这里s1和s2都没有声明变量的类型。编译器中有一个叫做推导的过程,根据上下文来推断这些类型。

但是也不是都能使用的,开发时要主要一般都省略,除非加上类型会让程序更清晰。但是编译器出现了错误,那还是加上吧。

类型推导中值得注意的是优先使用泛型类型

当然Lambda表达式没有名字也没有文档,只有便于理解以及代码量只有两三行那种才要使用Lambda。

方法引用

双冒号操作符

java还提供了一种比Lambda更加简洁的生成函数对象的方式:方法引用。

1
2
3
String[] newWay = "Improving code with Lambda expressions in Java 8".split(" ");
Arrays.sort(newWay, String::compareToIgnoreCase);
System.out.println(String.join(",", newWay));

双冒号(::)操作符是 Java 中的方法引用。 当们使用一个方法的引用时,目标引用放在 :: 之前,目标引用提供的方法名称放在 :: 之后,即 目标引用::方法

使用方法引用可以减少样板代码。如果方法的参数越多,方法引用消除的样板代码就越多。

参考:

Java 8新特性:lambda表达式 - Blogs - 廖雪峰的官方网站 (liaoxuefeng.com)

Java 8 Lambda 表达式详解 - 程序员干货 - SegmentFault 思否

Java Lambda 表达式 | 菜鸟教程 (runoob.com)

Java 匿名类 - Java教程 - 菜鸟教程 (cainiaojc.com)