以下是對您博客內容的優化版本,在保留原有核心內容的基礎上,補充了Lambda表達式及Stream API的完整方法體系,并通過結構化排版和擴展說明提升可讀性。
Java Lambda表達式與Stream API全解析:從基礎到進階
一、Lambda表達式與Stream API基礎
Lambda表達式是Java 8引入的函數式編程特性,配合Stream API可高效處理集合數據。其核心優勢在于:
- 減少冗余代碼,提升可讀性
- 支持并行處理,優化性能
- 鏈式調用實現流式數據處理
二、Stream API核心方法詳解
以下以Student
類為例(類定義同原博客),展示Stream API的完整方法體系:
1. 數據轉換(Map系列)
作用:將流中元素轉換為新類型。
// 基礎map:轉換元素類型
List<Integer> ages = students.stream().map(Student::getAge) // 提取年齡,返回Stream<Integer>.collect(Collectors.toList()); // [18, 26, 30, 10, 10]// 特化map:返回基本類型流
IntStream ageStream = students.stream().mapToInt(Student::getAge); // 直接返回IntStream,避免裝箱開銷// flatMap:合并多層流(處理嵌套集合)
List<Integer> allScores = students.stream().flatMap(student -> student.getCourses().stream()) // 將每個學生的課程流合并為一個流.collect(Collectors.toList()); // 假設getCourses()返回List<Integer>
注意:map
處理單個元素轉換,flatMap
處理多層集合展開(如將Stream<List<T>>
轉為Stream<T>
)。
2. 數據過濾與去重
filter:按條件篩選元素。
List<Student> adultStudents = students.stream().filter(student -> student.getAge() > 18) // 保留年齡>18的學生.collect(Collectors.toList());
distinct:根據元素equals
和hashCode
去重。
List<Student> uniqueStudents = students.stream().distinct() // 去重,需Student重寫equals和hashCode.collect(Collectors.toList());
3. 排序與限制
sorted:排序(支持自定義比較器)。
// 自然排序(年齡升序)
List<Integer> sortedAges = students.stream().map(Student::getAge).sorted() // 等價于sorted(Comparator.naturalOrder()).collect(Collectors.toList()); // [10, 10, 18, 26, 30]// 自定義排序(年齡降序)
List<Student> sortedStudents = students.stream().sorted((s1, s2) -> s2.getAge() - s1.getAge()).collect(Collectors.toList());
limit/skip:限制流長度(limit
取前n個,skip
跳過前n個)。
List<Student> firstTwo = students.stream().limit(2) // 取前2個學生.collect(Collectors.toList());
4. 聚合與歸約(Reduce)
reduce:將流中元素聚合為單個結果。
// 計算年齡總和
int totalAge = students.stream().mapToInt(Student::getAge).sum(); // 更簡潔的歸約方式,等價于:// .reduce(0, (sum, age) -> sum + age);// 復雜歸約:找出年齡最大的學生
Student oldestStudent = students.stream().reduce((s1, s2) -> s1.getAge() > s2.getAge() ? s1 : s2).orElse(null);
5. 查找與匹配
findFirst/findAny:查找第一個/任意元素(并行流中findAny
效率更高)。
int firstAdultAge = students.stream().filter(s -> s.getAge() > 18).findFirst().map(Student::getAge).orElse(0); // 若無可選元素,返回0
allMatch/anyMatch/noneMatch:判斷流中元素是否滿足條件。
boolean hasTeenager = students.stream().anyMatch(s -> s.getAge() < 20); // 是否有青少年
6. 消費與調試(Peek)
peek:對流中元素執行操作(常用于調試)。
List<Student> debugList = students.stream().peek(s -> System.out.println("處理學生:" + s.getName())).collect(Collectors.toList());
7. 其他實用方法
count:統計元素數量。
long studentCount = students.stream().count();
collect:將流轉換為集合/Map等(配合Collectors
工具類)。
// 按年齡分組
Map<Integer, List<Student>> studentsByAge = students.stream().collect(Collectors.groupingBy(Student::getAge));// 提取姓名列表
List<String> names = students.stream().map(Student::getName).collect(Collectors.toList());
三、Lambda表達式進階用法
1. 方法引用(Method Reference)
簡化Lambda表達式,直接引用已有方法。
// 等價于 x -> x.getAge()
students.stream().map(Student::getAge);// 靜態方法引用
List<String> names = students.stream().map(Student::getName).collect(Collectors.toList());
2. 構造器引用
// 將Integer列表轉為Student對象列表(假設Student有Integer參數的構造器)
List<Student> studentList = ages.stream().map(Student::new) // 等價于 x -> new Student(x).collect(Collectors.toList());
四、性能優化與注意事項
- 惰性求值:Stream操作分為惰性(
filter
/map
)和及早(collect
/reduce
),需調用及早操作才會執行。 - 并行流:大數據量時使用
parallelStream()
提升性能,但需注意線程安全。 - 裝箱開銷:使用
mapToInt
/mapToLong
等特化方法避免自動裝箱。
五、完整示例:綜合應用
// 需求:統計年齡>20的學生姓名,按年齡降序排列,取前3個
List<String> result = students.stream().filter(s -> s.getAge() > 20) // 過濾年齡>20.sorted((s1, s2) -> s2.getAge() - s1.getAge()) // 年齡降序.limit(3) // 取前3個.map(Student::getName) // 提取姓名.collect(Collectors.toList()); // 轉換為列表
通過以上優化,內容覆蓋了Lambda與Stream API的核心方法,并補充了進階用法和性能建議,結構更清晰,示例更全面。如需進一步擴展,可加入并行流對比、自定義Collector實現等深度內容。