Java Stream API 详解(Java 8+)
1. Stream 操作分类
Stream 操作分为两类:
中间操作(Intermediate Operations)
返回新的
Stream
,可以链式调用(如filter
,map
,sorted
,distinct
)。惰性求值:只有遇到终止操作时才会执行。
终止操作(Terminal Operations)
返回非
Stream
结果(如collect
,count
,sum
,forEach
)。触发计算,执行所有中间操作。
2. 常用 Stream 操作
(1) 过滤:filter(Predicate<T>)
作用:筛选符合条件的元素。
示例:筛选以 "a"
开头的字符串。
java
List<String> list = List.of("apple", "banana", "avocado", "orange"); List<String> filtered = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList()); // 结果:["apple", "avocado"]
(2) 映射:map(Function<T, R>)
作用:将元素转换为另一种形式(如大小写转换、提取字段)。
示例:所有字符串转为大写。
java
List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList()); // 结果:["APPLE", "BANANA", "AVOCADO", "ORANGE"]
提取对象属性:
java
List<Person> people = ...; List<String> names = people.stream().map(Person::getName).collect(Collectors.toList());
(3) 排序:sorted()
/ sorted(Comparator<T>)
作用:按自然顺序或自定义比较器排序。
示例:按字母顺序排序。
java
List<String> sorted = list.stream().sorted().collect(Collectors.toList()); // 结果:["apple", "avocado", "banana", "orange"]
自定义排序(按字符串长度):
java
List<String> sortedByLength = list.stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList()); // 结果:["apple", "banana", "orange", "avocado"]
(4) 去重:distinct()
作用:去除重复元素(依赖 equals()
和 hashCode()
)。
示例:
java
List<String> withDuplicates = List.of("a", "b", "a", "c"); List<String> distinct = withDuplicates.stream().distinct().collect(Collectors.toList()); // 结果:["a", "b", "c"]
(5) 聚合操作
计数:count()
java
long count = list.stream().count(); // 4
求和:mapToInt()
+ sum()
java
List<String> numbers = List.of("1", "2", "3"); int sum = numbers.stream().mapToInt(Integer::parseInt).sum(); // 6
求最大值/最小值
java
Optional<String> max = list.stream().max(Comparator.naturalOrder()); Optional<String> min = list.stream().min(Comparator.comparing(String::length));
匹配检查
anyMatch(Predicate<T>)
(任一元素匹配)allMatch(Predicate<T>)
(所有元素匹配)noneMatch(Predicate<T>)
(无元素匹配)
java
boolean hasA = list.stream().anyMatch(s -> s.contains("a")); // true
3. 终止操作:collect(Collectors.toList())
collect()
是常用的终止操作,用于将流转换为集合或其他数据结构。
常见 Collectors
方法:
方法 | 作用 |
---|---|
Collectors.toList() | 转为 List |
Collectors.toSet() | 转为 Set (自动去重) |
Collectors.joining(delimiter) | 拼接字符串 |
Collectors.groupingBy(Function) | 按条件分组 |
Collectors.partitioningBy(Predicate) | 按条件分区(true/false) |
示例:
java
// 拼接字符串 String joined = list.stream().collect(Collectors.joining(", ")); // 结果:"apple, banana, avocado, orange"// 分组(按首字母) Map<Character, List<String>> grouped = list.stream().collect(Collectors.groupingBy(s -> s.charAt(0))); // 结果:{'a': ["apple", "avocado"], 'b': ["banana"], 'o': ["orange"]}
4. 并行流(Parallel Stream)
通过 parallelStream()
利用多核 CPU 加速计算(适合大数据量)。
示例:
java
List<String> parallelProcessed = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
注意:
并行流不保证顺序。
小数据量可能更慢(线程开销)。
5. 完整示例
java
List<String> fruits = List.of("apple", "banana", "avocado", "orange", "apple");// 过滤 + 映射 + 去重 + 排序 List<String> result = fruits.stream().filter(s -> s.length() > 5) // 筛选长度 >5.map(String::toUpperCase) // 转大写.distinct() // 去重.sorted() // 排序.collect(Collectors.toList()); // 转为 List// 结果:["AVOCADO", "BANANA", "ORANGE"]
6. 总结
操作 | 方法 | 示例 |
---|---|---|
过滤 | filter(Predicate) | .filter(s -> s.startsWith("a")) |
映射 | map(Function) | .map(String::toUpperCase) |
排序 | sorted() | .sorted(Comparator.reverseOrder()) |
去重 | distinct() | .distinct() |
聚合 | count() , sum() | .mapToInt(Integer::parseInt).sum() |
收集 | collect(Collectors.toList()) | .collect(Collectors.joining(", ")) |
适用场景:
需要对集合进行复杂处理(如过滤、转换、分组)。
代码可读性比性能更重要(小数据量)。
并行流适合大数据计算(如日志分析、批量处理)。
传统循环 vs Stream:
java
// 传统方式(繁琐) List<String> filtered = new ArrayList<>(); for (String s : list) {if (s.startsWith("a")) {filtered.add(s.toUpperCase());} }// Stream 方式(简洁) List<String> filtered = list.stream().filter(s -> s.startsWith("a")).map(String::toUpperCase).collect(Collectors.toList());
Stream API 让代码更符合 “做什么” 而非 “怎么做” 的编程风格,推荐在 Java 8+ 项目中广泛使用!