Lambda 表达式是在 Java 8 中引入的,并被认为是 Java 8 中最重要的特性之一。Lambda 表达式支持函数式编程,并极大地简化了开发工作。Lambda 表达式的工作原理是基于函数接口的。函数接口是指只有一个方法需要实现的接口。Lambda 表达式提供了对该函数接口方法的实现。
Lambda 表达式极大地简化了函数式编程,并使得代码更加易读,而不需要任何样板代码。Lambda 表达式可以推断出所使用的参数类型,并可以在没有 return
关键字的情况下返回一个值。在简单的一行方法情况下,甚至可以省略花括号。
Lambda 表达式的语法
Lambda 表达式具有以下特征的语法:
参数 -> 表达式体
Java Lambda 表达式的特点
以下是 Lambda 表达式的一些重要特点:
-
可选类型声明:不需要声明参数的类型。编译器可以从参数的值推断出相同的信息。
-
可选的括号包围参数:不需要为单个参数声明括号。对于多个参数,则需要括号。
-
可选的花括号:如果表达式体包含单一语句,则不需要使用花括号。
-
可选的返回关键字:如果表达式体只有一个表达式需要返回值,则编译器会自动返回该值。需要花括号来指示表达式返回一个值。
Java Lambda 表达式示例
在这个例子中,我们有一个功能接口 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();
MathOperation addition = (int a, int b) -> a + b;
MathOperation subtraction = (a, b) -> a - b;
MathOperation multiplication = (int a, int b) -> { return a * b; };
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));
GreetingService greetService1 = message -> System.out.println("Hello " + message);
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);
}
}
输出: 如果我们编译并运行上面的程序,这将产生以下结果:
10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Mahesh
Hello Suresh
在上面的例子中需要注意的重要点如下:
Lambda 表达式主要用于定义函数接口(即只有一个方法的接口)的内联实现。在上面的例子中,我们使用了不同类型的 Lambda 表达式来定义 MathOperation
接口的操作方法。然后我们定义了 GreetingService
的 sayMessage
实现。
Lambda 表达式消除了匿名类的需求,并给 Java 提供了一个简单而强大的函数式编程能力。
Java Lambda 表达式的范围
使用 Lambda 表达式,您可以引用任何最终变量或实际上最终的变量(即只赋值一次)。如果一个变量第二次被赋值,Lambda 表达式会抛出编译错误。
在 Lambda 表达式中使用常量
在这个例子中,我们有一个功能接口 GreetingService
,它有一个方法 sayMessage
,我们使用它来向控制台打印一条消息。现在在 Java Tester
类中,我们有一个最终类字段 salutation
,它的值为 "Hello! "
。现在在 Lambda 表达式中,我们可以使用这个字段而不产生任何错误。
使用常量的 Lambda 表达式示例
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
在集合中使用 Lambda 表达式
从 Java 8 开始,几乎所有集合都增强以接受 Lambda 表达式来进行操作。例如,迭代列表、过滤列表、排序列表等等。在这个例子中,我们展示了如何迭代一个字符串列表并打印所有元素,以及如何仅使用 Lambda 表达式打印列表中的偶数。
使用 Lambda 表达式在集合中的示例
package com.tutorialspoint;
import java.util.ArrayList;
import java.util.List;
public class JavaTester {
public static void main(String args[]) {
List<String> list = new ArrayList<>();
list.add("java");
list.add("html");
list.add("python");
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);
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]