Java 简明教程

Java - Lambda Expressions

Java Lambda Expressions

Lambda expressions 在 Java 8 中引入,并被吹捧为最大的 feature of Java 8。Lambda 表达式促进了函数式编程并极大地简化了开发。Lambda 表达式基于函数式接口的原理。函数式接口是一个 interface ,仅需要一个 method 来实现。Lambda 表达式提供函数式接口方法的实现。

Lambda expression 极大地简化了函数式编程,使代码可读,且没有任何样板代码。Lambda 表达式可以推断出所用参数的类型,并且可以在没有 return 关键字的情况下返回一个值。对于简单的单语句方法,甚至可以消除花括号。

Lambda Expression Syntax

Lambda 表达式的特征在于以下语法。

parameter -> expression body

Characteristics of Java Lambda Expression

以下是 Lambda 表达式的几个重要特征。

  1. Optional type declaration − 无需声明参数的类型。 compiler 可从参数值推断参数类型。

  2. Optional parenthesis around parameter - 无需在括号中声明单个参数。对于多个参数,需要使用括号。

  3. Optional curly braces - 如果主体包含单个语句,则无需在表达式主体中使用大括号。

  4. Optional return keyword - 如果主体有一个要返回值的单语句表达式,编译器会自动返回该值。需要大括号来指出表达式返回一个值。

Java Lambda Expression Example

在此示例中,我们有一个 MathOperation 函数式接口,它有一个方法 operate,该方法可以接受两个 int 参数,执行操作并以 int 形式返回结果。利用 lambda 表达式,我们创建了 MathOperation operate 方法的四个不同实现,分别用于加、减、乘、除两个整数并获得相对结果。然后,我们有另一个函数式接口 GreetingService,它具有一个方法 sayMessage,我们用它来向控制台打印消息。

package com.tutorialspoint;

public class JavaTester {

   public static void main(String args[]) {
      JavaTester tester = new JavaTester();

      //with type declaration
      MathOperation addition = (int a, int b) -> a + b;

      //with out type declaration
      MathOperation subtraction = (a, b) -> a - b;

      //with return statement along with curly braces
      MathOperation multiplication = (int a, int b) -> { return a * b; };

      //without return statement and without curly braces
      MathOperation division = (int a, int b) -> a / b;

      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));

      //without parenthesis
      GreetingService greetService1 = message -> System.out.println("Hello " + message);

      //with parenthesis
      GreetingService greetService2 = (message) -> System.out.println("Hello " + message);

      greetService1.sayMessage("Mahesh");
      greetService2.sayMessage("Suresh");
   }

   interface MathOperation {
      int operation(int a, int b);
   }

   interface GreetingService {
      void sayMessage(String message);
   }

   private int operate(int a, int b, MathOperation mathOperation) {
      return mathOperation.operation(a, b);
   }
}

Output

让我们编译并运行上述程序,这将生成以下结果 −

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Mahesh
Hello Suresh

以下是在上面的示例中需要考虑的几个重要事项。

  1. Lambda 表达式主要用于定义函数式接口的内联实现,即仅具有单一方法的接口。在上面的示例中,我们使用了多种类型的 lambda 表达式来定义 MathOperation 接口的 operation 方法。然后,我们定义了 GreetingService 的 sayMessage 的实现。

  2. Lambda 表达式消除了对匿名类的需求,为 Java 提供了非常简单但功能强大的函数式编程功能。

Scope of Java Lambda Expression

使用 lambda 表达式,你可以引用任何 final 变量或有效 final 变量(只分配一次)。如果变量第二次分配了值,lambda 表达式将抛出一个编译错误。

Using Constant in Lambda Expression

在这个示例中,我们有一个函数接口 GreetingService,其中包含一个方法 sayMessage,我们用该方法向控制台打印一条消息。现在在 Java Tester 类中,我们有一个 final 类字段 salutation,它的值是“Hello! ”。现在在 lambda 表达式中,我们可以使用这个 final 字段而不出现任何错误。

Example to Use Constant in Lambda Expression

public class JavaTester {

   final static String salutation = "Hello! ";

   public static void main(String args[]) {
      GreetingService greetService1 = message -> System.out.println(salutation + message);
      greetService1.sayMessage("Mahesh");
   }

   interface GreetingService {
      void sayMessage(String message);
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

Hello! Mahesh

Using Lambda Expression in Collections

从 Java 8 开始,几乎所有 collections 都经过了增强,可以接受 lambda 表达式对它们执行操作。例如,迭代列表、筛选列表、对列表排序等。在本示例中,我们将展示如何迭代字符串列表并打印所有元素,以及如何使用 lambda 表达式仅打印列表中的偶数。

Example to Use Lambda Expression in Collections

package com.tutorialspoint;

import java.util.ArrayList;
import java.util.List;

public class JavaTester {

   public static void main(String args[]) {

	   // prepare a list of strings
	   List<String> list = new ArrayList<>();
	   list.add("java");
	   list.add("html");
	   list.add("python");

	   // print the list using a lambda expression
	   // here we're passing a lambda expression to forEach
	   // method of list object
	   list.forEach(i -> System.out.println(i));

	   List<Integer> numbers = new ArrayList<>();
	   numbers.add(1);
	   numbers.add(2);
	   numbers.add(3);
	   numbers.add(4);
	   numbers.add(5);
	   numbers.add(6);
	   numbers.add(7);
	   numbers.add(8);
	   System.out.println(numbers);

	   // filter the list using a lambda expression
	   // here we're passing a lambda expression to removeIf
	   // method of list object where we can checking
	   // if number is divisible by 2 or not
	   numbers.removeIf( n -> n%2 != 0);
	   System.out.println(numbers);
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

java
html
python
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 4, 6, 8]