Java 8 的流(Stream API)简介
Java 8 引入的 Stream API 是一个强大的工具,用于处理集合(如 List、Set)中的元素。它支持各种操作,包括过滤、排序、映射等,并且能够以声明式的方式表达复杂的查询操作。流操作可以是中间操作(返回流以便进一步处理)或终端操作(产生结果或副作用)。此外,Stream API 还支持并行执行,从而利用多核处理器的优势。
Stream 的基本概念
-
源
任何提供数据的集合(如List
、Set
、数组等)均可作为流的来源。 -
中间操作
返回新流对象,支持链式调用,惰性求值。常见操作包括:filter
(筛选)map
(映射)sorted
(排序)distinct
(去重)limit
(限制数量)skip
(跳过元素)flatMap
(扁平化映射)peek
(调试查看)
-
终端操作
触发流处理并生成结果,执行后流被消耗。常见操作包括:forEach
(遍历)collect
(收集到集合)reduce
(聚合)count
(统计数量)findFirst
/findAny
(查找元素)anyMatch
/allMatch
/noneMatch
(匹配验证)
创建 Stream 的方式
-
从集合创建
List<String> list = Arrays.asList("apple", "banana", "pear"); Stream<String> stream = list.stream();
-
从数组创建
String[] arr = {"apple", "banana", "pear"}; Stream<String> stream = Arrays.stream(arr);
-
生成无限流
// 迭代生成(0, 1, 2, ...) Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);// 随机生成 Stream<Double> randomStream = Stream.generate(Math::random);
中间操作详解
1. 筛选与切片
-
filter
:按条件筛选元素List<String> filtered = list.stream().filter(s -> s.length() > 3).collect(Collectors.toList());
-
distinct
:去重(需重写equals
和hashCode
)List<Integer> distinctList = Arrays.asList(1, 2, 2, 3).stream().distinct().collect(Collectors.toList()); // [1, 2, 3]
-
limit
:截取前 N 个元素List<String> firstTwo = list.stream().limit(2).collect(Collectors.toList());
-
skip
:跳过前 N 个元素List<String> skipped = list.stream().skip(1).collect(Collectors.toList());
2. 映射与扁平化
-
map
:元素类型转换List<String> upperCase = list.stream().map(String::toUpperCase).collect(Collectors.toList());
-
flatMap
:扁平化嵌套集合List<List<Integer>> nestedList = Arrays.asList(Arrays.asList(1, 2),Arrays.asList(3, 4) ); List<Integer> flatList = nestedList.stream().flatMap(List::stream).collect(Collectors.toList()); // [1, 2, 3, 4]
3. 排序
-
自然排序
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
-
自定义排序
List<Employee> sortedEmployees = employees.stream().sorted((e1, e2) -> e2.getAge() - e1.getAge()).collect(Collectors.toList());
4. 调试查看
peek
:遍历元素时执行操作(如打印)list.stream().peek(System.out::println).collect(Collectors.toList());
终端操作详解
1. 收集结果
-
收集到集合
List<String> listResult = Stream.of("a", "b", "c").collect(Collectors.toList());Set<String> setResult = Stream.of("apple", "banana", "pear").collect(Collectors.toSet());
-
分组与分区
Map<Integer, List<String>> grouped = list.stream().collect(Collectors.groupingBy(s -> s.length()));
2. 聚合操作
-
reduce
求和int sum = numbers.stream().reduce(0, (a, b) -> a + b);
-
拼接字符串
String joined = Stream.of("a", "b", "c").reduce("", (a, b) -> a + b); // "abc"
-
无初始值的聚合
Optional<Integer> max = numbers.stream().reduce(Integer::max);
3. 查找与匹配
-
findFirst
:获取第一个元素Optional<String> first = list.stream().filter(s -> s.startsWith("a")).findFirst();
-
findAny
:获取任意元素(并行流中可能乱序)Optional<String> any = list.parallelStream().findAny();
-
max
/min
:获取极值Optional<Integer> maxNumber = numbers.stream().max(Integer::compare);
4. 匹配验证
-
anyMatch
:至少一个元素满足条件boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
-
allMatch
:所有元素满足条件boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
-
noneMatch
:无元素满足条件boolean noEven = numbers.stream().noneMatch(n -> n % 2 == 0);
5. 统计与转换
-
count
:统计元素数量long count = list.stream().filter(s -> s.length() > 3).count();
-
toArray
:转换为数组String[] array = list.stream().toArray(String[]::new);
-
数值统计
IntSummaryStatistics stats = numbers.stream().mapToInt(Integer::intValue).summaryStatistics(); System.out.println(stats.getAverage()); // 平均值
6. 遍历操作
forEach
:执行副作用操作list.stream().forEach(System.out::println);
并行流(Parallel Stream)
-
启用并行流
List<String> list = Arrays.asList("apple", "banana", "pear"); list.parallelStream().forEach(System.out::println);
-
注意事项
- 并行流可能提高大数据集处理性能。
- 需确保线程安全性(如避免共享状态修改)。
- 并行排序(
sorted()
)可能不稳定,需谨慎使用。
注意事项
-
中间操作顺序
逻辑顺序需合理(如先filter
再map
)。 -
对象去重
使用distinct()
时需重写hashCode()
和equals()
。 -
流复用问题
终端操作后流被消耗,需重新创建流:Stream<String> stream = list.stream(); stream.forEach(System.out::println); // 首次使用 stream.forEach(System.out::println); // 报错!流已关闭
-
安全获取值
使用Optional
的orElse()
、orElseGet()
或orElseThrow()
避免空指针。
总结
Java 8 Stream API 通过声明式编程简化了集合操作,支持链式调用和并行处理。合理使用中间操作(如 filter
、map
)和终端操作(如 collect
、reduce
),可高效完成数据聚合、过滤及验证。结合并行流可显著提升大数据集处理性能,但需注意线程安全性和操作顺序。