原文: https://javatutorial.net/java-lambda-expressions-tutorial

Java 8 引入了 Lambda 表达式,它是引入的最大(甚至不是最大)功能之一,因为 Lambda 表达式使功能编程成为可能,并且使您的代码更整洁,并从整体上极大地简化了整个代码的实现。

例如,当您必须使用匿名类并且该类非常简单(例如仅包含几个(或更少)方法)时,您会遇到非常不清楚且难以阅读/维护的语法。 这是 Lambda 表达式发挥作用的时候。

Java Lambda 表达式教程 - 图1

让我们比较一下使用 Lambda 表达式和不使用 Lambda 表达式

假设有一个类,该类具有默认情况下按升序对元素进行排序的方法(例如Comparator)。 此类使用compare来对元素进行排序。 让我们覆盖它。

不使用 Lambda 表达式

  1. Comparator<Double> sorter = new Comparator<Double>() {
  2. @Override
  3. public int compare(Double x, Double y) {
  4. return y.compareTo(x);
  5. }
  6. };

使用 Lambda 表达式

  1. Comparator<Double> lambdaComparator = (x, y) -> y.compareTo(x);

我相信您会注意到两种方法之间的区别。 两者都导致同一件事,这颠倒了该方法对元素进行排序的顺序(从升序到降序,对您的比较器开玩笑!)。

因此,仅通过查看此示例,使用 lambda 表达式的一个关键优势就是可以减少键入的代码。 对于我们懒惰的程序员来说,这是一个很好的例子。 但是,人们可能会争辩说,由于这种简单性,实际上使记住语法变得更加困难。 没错,这将是一个缺点。 最初,语法可能有点难以记住,但是一旦您记住它,就可以编写简洁的代码,该代码也允许您实现Functional接口。

让我们看看 Lambda 表达式的更多示例。

首先,如我之前所说,语法起初有点令人生畏。

如果您要“覆盖”的函数没有任何参数,则只需键入() -> {body}。 另一方面,如果只有一个参数,则键入x -> {body}。 对于两个或更多参数,您将具有(x, y, z -> {body}

循环播放

  1. import java.util.*;
  2. public class LambdaExpressionDemo {
  3. public static void main(String[] args) {
  4. List<int> listOfNumbers = new ArrayList<int>();
  5. listOfNumbers.add(1);
  6. listOfNumbers.add(2);
  7. listOfNumbers.add(3);
  8. listOfNumbers.add(4);
  9. listOfNumbers.add(5);
  10. listOfNumbers.add(6);
  11. listOfNumbers.add(7);
  12. listOfNumbers.add(8);
  13. listOfNumbers.forEach(
  14. (num) -> System.out.println(num)
  15. );
  16. }
  17. }

注意,在forEach循环的主体中,我省略了{}花括号。 这是因为主体仅包含一行。 如果我有两行或更多行,假设另一个打印语句,那么我将拥有大括号,如下所示:

  1. import java.util.*;
  2. public class LambdaExpressionDemo {
  3. public static void main(String[] args) {
  4. List<int> listOfNumbers = new ArrayList<int>();
  5. listOfNumbers.add(1);
  6. listOfNumbers.add(2);
  7. listOfNumbers.add(3);
  8. listOfNumbers.add(4);
  9. listOfNumbers.add(5);
  10. listOfNumbers.add(6);
  11. listOfNumbers.add(7);
  12. listOfNumbers.add(8);
  13. listOfNumbers.forEach(
  14. (num) -> {
  15. System.out.println(num);
  16. System.out.println(num);
  17. );
  18. }
  19. }

从 Lambda 表达式返回值

您也可以像使用方法一样使用 lambda 表达式返回值。 这里要注意的一个关键是return关键字是可选的。 您可以忽略它,编译器知道它的工作。

语法类似于我们之前使用的语法。

  1. (x, y) -> {
  2. return x > y;
  3. }

因此,如果我们再次查看 Lambda 表达式提供的内容,我们可以得出结论,它为我们提供了可选的类型声明(无需声明参数的类型),可选的花括号,可选的return关键字(因为编译器自动返回值) (如果主体具有返回值的符号表达式)和参数周围的可选括号。