Java 8 Stream API:第二部分 - Pluralsight

作者:API传播员 · 2025-11-12 · 阅读时间:4分钟

在这篇关于 Java 8 流 API 的教程第二部分中,我们将继续探索如何以函数式编程的方式操作 Java 流。本文将深入介绍流的缩减操作、收集器的使用以及并行流的最佳实践,帮助您更高效地处理数据流。


函数式流编程简介

在 Java 8 中,流 API 提供了一种函数式编程风格来处理数据流。通过流操作,可以轻松实现数据的过滤、映射和归约等操作。接下来,我们将重点介绍流的缩减操作以及如何使用 reduce()collect() 方法。


缩减操作与 reduce() 方法

缩减操作是将流中的元素组合成单个值的过程,例如求和、计算最大值或计数元素。Stream 接口提供了两种 reduce() 方法:

单参数版本的 reduce()

单参数版本的 reduce() 使用流的第一个元素作为初始值,并依次将流中的元素与累加器进行操作。例如,以下是一个求和的示例:

List numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
                 .reduce((a, b) -> a + b)
                 .orElse(0);

双参数版本的 reduce()

如果需要指定初始值,可以使用双参数版本的 reduce()

int sum = numbers.stream()
                 .reduce(0, (a, b) -> a + b);

三参数版本的 reduce()

当需要返回与流元素类型不同的结果时,可以使用三参数版本的 reduce()。例如:

int sum = numbers.stream()
                 .reduce(0, Integer::sum, Integer::sum);

三参数版本的 reduce() 特别适合并行流,因为它允许在多个线程中独立计算部分结果,然后将这些结果合并。


收集操作与 collect() 方法

collect() 方法是流 API 中另一种重要的终端操作,用于将流的元素收集到集合或其他数据结构中。Collectors 类提供了多种内置的收集器:

常见的收集器

  • toList:将元素收集到 List 中。
  • toSet:将元素收集到 Set 中。
  • toMap:将元素收集到 Map 中。
  • joining:将元素连接成字符串。
  • groupingBy:根据分类函数将元素分组。
  • partitioningBy:根据谓词将元素分区。

以下是一个使用 groupingBy() 的示例:

Map<String, List> grouped = items.stream()
                                         .collect(Collectors.groupingBy(String::toUpperCase));

自定义收集器

collect() 方法还支持自定义收集器,通过提供 SupplierBiConsumerBiFunction 参数来实现。例如:

List result = numbers.stream()
                              .collect(ArrayList::new, List::add, List::addAll);

并行流的使用与注意事项

并行流通过 Fork/Join 框架实现并行处理,默认线程数等于 CPU 核心数。并行流适用于顺序无关且操作无状态的场景,例如统计计算或大规模数据处理。

并行流的规则

  1. 对于小数据集,顺序流通常性能更优。
  2. 避免在并行流中使用有状态操作(如 sorted())或基于顺序的操作(如 findFirst())。
  3. 并行流适合计算密集型操作。
  4. 在使用并行流前,建议通过基准测试验证性能。

以下是一个并行流的示例:

int sum = numbers.parallelStream()
                 .reduce(0, Integer::sum);

并行流中的 reduce()collect()

并行流中的 reduce()collect() 方法需要满足结合性和同一性要求,以确保操作的正确性。例如:

int factorial = IntStream.rangeClosed(1, 10)
                         .parallel()
                         .reduce(1, (a, b) -> a * b);

总结

通过本文的学习,您已经了解了 Java 8 流 API 中的缩减操作、收集器的使用以及并行流的最佳实践。在实际开发中,合理选择流操作方式可以显著提升代码的可读性和性能。希望您能将这些知识应用到实际项目中,充分发挥流 API 的强大功能。


原文链接: https://www.pluralsight.com/resources/blog/guides/java-8-stream-api-part-2