原文: https://javatutorial.net/java-lambda-expressions-tutorial
Java 8 引入了 Lambda 表达式,它是引入的最大(甚至不是最大)功能之一,因为 Lambda 表达式使功能编程成为可能,并且使您的代码更整洁,并从整体上极大地简化了整个代码的实现。
例如,当您必须使用匿名类并且该类非常简单(例如仅包含几个(或更少)方法)时,您会遇到非常不清楚且难以阅读/维护的语法。 这是 Lambda 表达式发挥作用的时候。
让我们比较一下使用 Lambda 表达式和不使用 Lambda 表达式
假设有一个类,该类具有默认情况下按升序对元素进行排序的方法(例如Comparator
)。 此类使用compare
来对元素进行排序。 让我们覆盖它。
不使用 Lambda 表达式
Comparator<Double> sorter = new Comparator<Double>() {
@Override
public int compare(Double x, Double y) {
return y.compareTo(x);
}
};
使用 Lambda 表达式
Comparator<Double> lambdaComparator = (x, y) -> y.compareTo(x);
我相信您会注意到两种方法之间的区别。 两者都导致同一件事,这颠倒了该方法对元素进行排序的顺序(从升序到降序,对您的比较器开玩笑!)。
因此,仅通过查看此示例,使用 lambda 表达式的一个关键优势就是可以减少键入的代码。 对于我们懒惰的程序员来说,这是一个很好的例子。 但是,人们可能会争辩说,由于这种简单性,实际上使记住语法变得更加困难。 没错,这将是一个缺点。 最初,语法可能有点难以记住,但是一旦您记住它,就可以编写简洁的代码,该代码也允许您实现Functional
接口。
让我们看看 Lambda 表达式的更多示例。
首先,如我之前所说,语法起初有点令人生畏。
如果您要“覆盖”的函数没有任何参数,则只需键入() -> {body}
。 另一方面,如果只有一个参数,则键入x -> {body}
。 对于两个或更多参数,您将具有(x, y, z -> {body}
。
循环播放
import java.util.*;
public class LambdaExpressionDemo {
public static void main(String[] args) {
List<int> listOfNumbers = new ArrayList<int>();
listOfNumbers.add(1);
listOfNumbers.add(2);
listOfNumbers.add(3);
listOfNumbers.add(4);
listOfNumbers.add(5);
listOfNumbers.add(6);
listOfNumbers.add(7);
listOfNumbers.add(8);
listOfNumbers.forEach(
(num) -> System.out.println(num)
);
}
}
注意,在forEach
循环的主体中,我省略了{}
花括号。 这是因为主体仅包含一行。 如果我有两行或更多行,假设另一个打印语句,那么我将拥有大括号,如下所示:
import java.util.*;
public class LambdaExpressionDemo {
public static void main(String[] args) {
List<int> listOfNumbers = new ArrayList<int>();
listOfNumbers.add(1);
listOfNumbers.add(2);
listOfNumbers.add(3);
listOfNumbers.add(4);
listOfNumbers.add(5);
listOfNumbers.add(6);
listOfNumbers.add(7);
listOfNumbers.add(8);
listOfNumbers.forEach(
(num) -> {
System.out.println(num);
System.out.println(num);
);
}
}
从 Lambda 表达式返回值
您也可以像使用方法一样使用 lambda 表达式返回值。 这里要注意的一个关键是return
关键字是可选的。 您可以忽略它,编译器知道它的工作。
语法类似于我们之前使用的语法。
(x, y) -> {
return x > y;
}
因此,如果我们再次查看 Lambda 表达式提供的内容,我们可以得出结论,它为我们提供了可选的类型声明(无需声明参数的类型),可选的花括号,可选的return
关键字(因为编译器自动返回值) (如果主体具有返回值的符号表达式)和参数周围的可选括号。