第3课java_Lambda表达式_StreamAPI
热度🔥:97 免费课程
授课语音
Java8的Lambda和流式编程
1. 介绍
Java8引入了Lambda表达式和Stream API的强大特性,旨在简化代码,提高可读性和可维护性,极大地提高了开发效率。
Lambda表达式
Lambda表达式是一种函数式编程的方式,它允许函数作为参数传递。实际开发中,Lambda表达式被广泛应用于集合操作和并发编程。其主要特性包括:
语法简洁:
- 单个表达式:
(params) -> expression
- 多个语句:
{ (params) -> {statements}}
- 单个表达式:
函数式接口:只包含一个抽象方法的接口,例如
Runnable
和Callable
等。方法引用:使用
::
符号引用方法,例如String::length
。
Stream API
Stream API提供了一种声明式的方式来处理集合,包括过滤、映射、聚合等操作。流分为顺序流(顺序处理)和并行流(并行处理,充分利用多核处理器)。其主要特性包括:
创建流:可以通过多种方式创建流,例如:
collection.stream()
从集合中创建Arrays.stream(array)
从数组创建Stream.generate()
使用生成器创建Stream.iterate()
使用迭代器创建
中间操作:返回一个新的流,可以链式使用,例如:
filter()
过滤map()
映射sorted()
排序
终止操作:返回一个非流结果,并触发流处理,例如:
forEach()
遍历collect()
reduce()
聚合操作:方便对数据进行统计和分析,例如:
count
、sum
、average
、max
、min
收集操作:将流的元素收集到集合中,例如:
toList
、toSet
、toMap
2. 代码案例
package com.zhilitech.lambda;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
// 定义Person类
class Person {
private String name; // 姓名
private int age; // 年龄
private String occupation; // 职业
// 构造函数
public Person(String name, int age, String occupation) {
this.name = name;
this.age = age;
this.occupation = occupation;
}
// Getter方法
public String getName() {
return name; // 返回姓名
}
public int getAge() {
return age; // 返回年龄
}
public String getOccupation() {
return occupation; // 返回职业
}
@Override
public String toString() {
// 返回Person对象的字符串表示
return "Person{name='" + name + "', age=" + age + ", occupation='" + occupation + "'}";
}
}
public class LambdaStreamEnhancedExample {
public static void main(String[] args) {
// 创建一个Person类的列表
List<Person> people = Arrays.asList(
new Person("Alice", 30, "Engineer"),
new Person("Bob", 25, "Designer"),
new Person("Charlie", 35, "Manager"),
new Person("David", 40, "Engineer"),
new Person("Eve", 28, "Designer")
);
// 使用自定义函数式接口将姓名转换为大写
Function<Person, String> nameToUpperCase = person -> person.getName().toUpperCase();
List<String> upperCaseNames = people.stream()
.map(nameToUpperCase) // 使用map操作将每个姓名转换为大写
.toList();
System.out.println("使用自定义函数式接口转换的姓名为大写: " + upperCaseNames);
// 输出: [ALICE, BOB, CHARLIE, DAVID, EVE]
// 使用方法引用获取姓名
List<String> namesViaMethodReference = people.stream()
.map(Person::getName) // 通过方法引用获取姓名
.toList();
System.out.println("使用方法引用获取的姓名: " + namesViaMethodReference);
// 输出: [Alice, Bob, Charlie, David, Eve]
// 使用Stream API计算所有人员的平均年龄
OptionalDouble averageAgeOptional = people.stream()
.mapToInt(Person::getAge) // 映射年龄
.average(); // 计算平均值
if (averageAgeOptional.isPresent()) {
double averageAge = averageAgeOptional.getAsDouble(); // 获取平均年龄
System.out.println("所有人员的平均年龄: " + averageAge);
// 输出: 31.6
} else {
System.out.println("没有可用的平均年龄。");
}
double averageAge = averageAgeOptional.orElse(0);
System.out.println("所有人员的平均年龄: " + averageAge);
// 输出: 31.6
// 使用Stream API根据职业进行分组
Map<String, List<Person>> peopleByOccupation = people.stream()
.collect(Collectors.groupingBy(Person::getOccupation)); // 按职业分组
System.out.println("按职业分组的人: " + peopleByOccupation);
// 输出: {Engineer=[...], Designer=[...], Manager=[...]}
// 使用Stream API对人员按年龄排序
List<Person> sortedByAge = people.stream()
.sorted(Comparator.comparingInt(Person::getAge)) // 按年龄排序
.toList();
System.out.println("按年龄排序的人: " + sortedByAge);
// 输出: [Person{name='Bob', age=25, ...}, ...]
// 使用reduce计算总年龄
int totalAge = people.stream()
.map(Person::getAge) // 映射年龄
.reduce(0, Integer::sum); // 计算总和
System.out.println("所有人员的总年龄: " + totalAge);
// 输出: 158
// 使用toMap生成一个以姓名为键、年龄为值的Map
Map<String, Integer> nameToAgeMap = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge)); // 生成姓名与年龄的映射
System.out.println("姓名与年龄的映射: " + nameToAgeMap);
// 输出: {Alice=30, Bob=25, ...}
// 使用toSet生成一个包含所有职业的Set
Set<String> occupationsSet = people.stream()
.map(Person::getOccupation) // 映射职业
.collect(Collectors.toSet()); // 收集到Set中
System.out.println("所有职业的集合: " + occupationsSet);
// 输出: [Designer, Manager, Engineer]
// 使用并行流进行并行处理
List<Person> sortedByAgeParallel = people.parallelStream()
.sorted(Comparator.comparingInt(Person::getAge)) // 使用并行流按年龄排序
.toList();
System.out.println("使用并行流按年龄排序的人: " + sortedByAgeParallel);
// 输出: [Person{name='Bob', age=25, ...}, ...]
}
}
在这个代码示例中,我们定义了一个Person
类,包含姓名、年龄和职业。我们创建了一个List
,然后使用Lambda表达式和Stream API对人员数据进行各种操作,包括转换姓名、计算平均年龄、按职业分组、排序、计算总年龄等。通过使用方法引用和函数式接口,我们能够更简洁地处理数据,提高了代码的可读性和可维护性。