Java 知识量:11 - 45 - 220
Lambda表达式是Java 8中引入的一个新特性,其主要用于简化函数式编程。Lambda表达式在Java中主要用于创建匿名方法。这种表达式实际上是一种匿名函数,它允许我们将函数作为方法参数进行传递,或者将代码看作数据。
Lambda表达式的基本语法如下:
(parameter) -> expression
或
(parameter) -> { statements; }
其中:
parameter:这是Lambda表达式的参数列表。参数类型是可选的,也可以直接推断。例如,a -> a + 1 和 (int a) -> a + 1 是等效的。
->:这个符号叫做Lambda操作符或箭头操作符,它将Lambda表达式的参数列表和体分开。
expression:这是Lambda表达式的主体。如果主体包含一个以上的语句,那么它需要被包含在大括号 {} 中。
例如,可以使用Lambda表达式来创建一个Runnable接口的实例,如下所示:
Runnable runnable = () -> System.out.println("Hello World"); new Thread(runnable).start();
在这个例子中,首先创建了一个没有参数的Lambda表达式,它实现了Runnable接口的唯一方法run()。然后我们创建了一个新的线程并启动它,新线程将运行Lambda表达式定义的任务。
Lambda表达式还可以用于简化集合操作。例如,可以使用Lambda表达式来过滤一个列表:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList());
在这个例子中,使用Lambda表达式来定义过滤条件,然后使用Stream API来处理列表。
方法引用是一种使用现有方法的方式来代替Lambda表达式的方式。它可以看作是一种特殊的Lambda表达式,其中函数体只包含一个方法调用。方法引用的语法如下:
::methodName
其中,methodName是要调用的方法的名称。如果方法是静态的,可以使用类名来限定方法名称;如果方法是实例方法,可以使用对象来限定方法名称。
例如,下面的代码展示了如何使用方法引用来实现一个接口:
interface GreetingService { void sayMessage(String message); } public class Main { public static void main(String[] args) { GreetingService greetingService = Main::sayHello; greetingService.sayMessage("world"); } public static void sayHello(String message) { System.out.println("Hello " + message); } }
在这个例子中,使用方法引用来实现sayMessage方法。将Main类的sayHello方法作为方法引用传递给greetingService变量。最后,调用sayMessage方法来执行方法引用。
函数式编程是一种编程范式,它将计算视为数学上的函数求值,并避免改变状态和使用可变数据。在 Java 中,从 Java 8 开始,函数式编程得到了支持。下面是一个使用 Lambda 表达式进行函数式编程的示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 使用 Lambda 表达式进行过滤 List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); // 使用 Lambda 表达式进行映射 List<Integer> squares = numbers.stream() .map(n -> n * n) .collect(Collectors.toList()); // 使用 Lambda 表达式进行排序 List<Integer> sortedNumbers = numbers.stream() .sorted() .collect(Collectors.toList()); // 使用 Lambda 表达式进行求和 int sum = numbers.stream() .reduce(0, (a, b) -> a + b);
在这个示例中,首先创建了一个整数列表 numbers,然后使用 Lambda 表达式对列表进行过滤、映射、排序和求和操作。在过滤操作中,使用 Lambda 表达式 n -> n % 2 == 0 来判断一个数是否为偶数;在映射操作中,使用 Lambda 表达式 n -> n * n 来计算一个数的平方;在排序操作中,使用 Lambda 表达式默认的排序规则对列表进行排序;在求和操作中,使用 Lambda 表达式 (a, b) -> a + b 来计算列表中所有数的和。
Lambda 表达式的语法非常简洁,它由参数列表、箭头符号 -> 和 Lambda 体组成。在上面的示例中,使用了不同的 Lambda 表达式来进行不同的操作,这些表达式都非常简洁易懂。通过使用 Lambda 表达式,可以将代码看作数据,并将其作为方法的参数进行传递,这使得编写函数式代码变得更加简单和直观。
Lambda 表达式在 Java 中被用作一种简洁、易读的方式来表示函数式接口。它们可以捕获和使用在其主体中声明的变量。
词法作用域:在 Java 中,Lambda 表达式的词法作用域与其封闭的方法或构造函数的词法作用域相同。这意味着,Lambda 表达式可以访问其封闭方法或构造函数的所有可见变量。封闭方法或构造函数的成员变量对 Lambda 表达式来说是可见的,可以被直接访问。
局部变量:Lambda 表达式可以在其主体中定义局部变量。这些变量仅在 Lambda 表达式的主体中存在,不能被其封闭的方法或构造函数访问。此外,Lambda 表达式还可以在其主体中访问其封闭方法或构造函数的局部变量,但这些变量必须被声明为 final 或 effectively final。
下面是一个例子:
public class Test { int x = 10; // 成员变量 public void test() { int y = 20; // 局部变量 Runnable r = () -> { int z = 30; // Lambda 表达式中的局部变量 System.out.println(x); // 访问成员变量 x System.out.println(y); // 访问局部变量 y System.out.println(z); // 访问 Lambda 表达式中的局部变量 z }; r.run(); } }
在这个例子中,Lambda 表达式可以访问成员变量 x 和局部变量 y,因为它们都是 final 或 effectively final 的。此外,Lambda 表达式还定义了其自己的局部变量 z。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6