Java Lambda 表达式详解及其用法 —— 含集合操作示例
Lambda 表达式自 Java 8 引入以来,大大简化了代码的书写,特别是在集合操作和流处理(Stream API)方面。本文将详细介绍 Lambda 表达式的概念、使用方法及其在集合中的应用,并结合示例说明如何使用 Lambda 表达式进行集合的转换和处理。
1. 什么是 Lambda 表达式?
Lambda 表达式是一种可以把函数作为参数的简洁表达方式,主要用于替代匿名内部类的冗长语法。它使得函数式编程风格更容易实现。基本语法格式如下:
(parameters) -> expression
或者:
(parameters) -> { statements; }
parameters
:表示输入参数列表,可以没有、一个或多个参数。->
:Lambda 操作符,将参数和方法体分开。expression
/statements
:可以是单个表达式或代码块,作为方法体执行。
基本示例:
// 使用 lambda 实现一个简单的 Runnable
Runnable r = () -> System.out.println("Hello, Lambda!");
r.run(); // 输出 "Hello, Lambda!"
2. 函数式接口(Functional Interface)
Lambda 表达式通常用于实现函数式接口。函数式接口是只包含一个抽象方法的接口,Java 8 提供了多个常用的函数式接口,比如 Consumer
、Function
、Predicate
和 Supplier
等。
自定义函数式接口示例:
@FunctionalInterface
interface MyFunction {
int apply(int x);
}
MyFunction square = (x) -> x * x;
System.out.println(square.apply(5)); // 输出 25
3. 集合操作中的 Lambda 表达式
Lambda 表达式在集合操作中的应用尤为广泛,尤其是在使用 Java 8 的 Stream API 处理集合时,可以大大简化代码。下面我们将通过几个具体的例子展示如何用 Lambda 表达式操作集合,如将集合转换为 List
或 Map
,以及过滤、排序等。
3.1 使用 Lambda 表达式将集合转为 List
假设我们有一个包含字符串的集合,现在希望将所有以"A"开头的字符串转换为大写并收集到新的列表中:
import java.util.*;
import java.util.stream.*;
public class LambdaToListExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Ann");
// 使用Lambda表达式进行过滤和转换
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A")) // 过滤以"A"开头的名字
.map(String::toUpperCase) // 将名字转换为大写
.collect(Collectors.toList()); // 收集到List
System.out.println(filteredNames); // 输出 [ALICE, ANN]
}
}
3.2 使用 Lambda 表达式将集合转为 Map
将集合转为 Map
是常见操作,特别是在需要通过某个字段来索引对象时。我们可以通过 Collectors.toMap()
方法来实现这一功能。
示例:将一组对象列表转换为以其某个属性为键的 Map
import java.util.*;
import java.util.stream.*;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override
public String toString() {
return name + ": " + age;
}
}
public class LambdaToMapExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
// 将Person对象转为Map,以名字为键,Person对象为值
Map<String, Person> personMap = people.stream()
.collect(Collectors.toMap(Person::getName, person -> person));
System.out.println(personMap);
// 输出:{Alice=Alice: 30, Bob=Bob: 25, Charlie=Charlie: 35}
}
}
3.3 集合的过滤与排序
使用 Stream API 结合 Lambda 表达式,可以对集合中的元素进行过滤和排序。
示例:过滤并按年龄排序
import java.util.*;
import java.util.stream.*;
public class LambdaFilterAndSortExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
// 过滤出年龄大于 25 的人并按年龄排序
List<Person> sortedPeople = people.stream()
.filter(person -> person.getAge() > 25)
.sorted(Comparator.comparing(Person::getAge))
.collect(Collectors.toList());
sortedPeople.forEach(System.out::println);
// 输出:
// Alice: 30
// Charlie: 35
}
}
3.4 使用 Lambda 表达式分组
Stream API 提供了 Collectors.groupingBy()
方法,用于根据某个条件对集合中的元素进行分组。
示例:根据年龄段对人进行分组
import java.util.*;
import java.util.stream.*;
public class LambdaGroupingExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35),
new Person("David", 25)
);
// 根据年龄进行分组
Map<Integer, List<Person>> peopleByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
System.out.println(peopleByAge);
// 输出:{25=[Bob: 25, David: 25], 30=[Alice: 30], 35=[Charlie: 35]}
}
}
3.5 使用 Lambda 表达式求和与聚合操作
可以通过 Collectors.summingInt()
、Collectors.averagingInt()
等方法,轻松实现集合中元素的求和、平均值等聚合操作。
示例:计算所有人的总年龄
import java.util.*;
import java.util.stream.*;
public class LambdaSumExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
// 计算所有人的总年龄
int totalAge = people.stream()
.collect(Collectors.summingInt(Person::getAge));
System.out.println("Total Age: " + totalAge); // 输出 "Total Age: 90"
}
}
4. 方法引用(Method References)
Lambda 表达式的另一种简化形式是方法引用,可以直接引用现有的方法或构造函数。常见的形式包括:
- 静态方法引用:
ClassName::methodName
- 实例方法引用:
instance::methodName
- 构造函数引用:
ClassName::new
示例:使用方法引用代替 Lambda 表达式
import java.util.*;
import java.util.stream.*;
public class MethodReferenceExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用方法引用代替Lambda表达式
names.forEach(System.out::println);
// 输出:
// Alice
// Bob
// Charlie
}
}
5. 总结
通过以上例子,我们可以看到 Lambda 表达式在 Java 8 中的强大功能。它极大地简化了集合的处理,特别是结合 Stream API,可以轻松实现集合的过滤、排序、转换、分组等操作。Lambda 表达式使得 Java 代码更加简洁、易读,也更符合现代函数式编程的风格。
在实际开发中,合理使用 Lambda 表达式不仅可以减少冗余代码,还能提高代码的可维护性和扩展性。
希望通过这些例子,能帮助你更好地理解和应用 Java 中的 Lambda 表达式。如果你有更多问题或想了解更复杂的应用场景,欢迎继续探讨!