跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Java Stream归约
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:Java Stream归约}} '''Java Stream归约'''(Reduction)是Java Stream API中的核心操作之一,它允许将流中的元素通过特定规则合并为一个结果。归约操作广泛应用于数据聚合、统计和转换场景,是函数式编程的重要概念。 == 概述 == 归约操作通过组合流中的元素,逐步生成最终结果。常见的归约操作包括求和、求最大值、字符串拼接等。Java Stream API提供了两种主要归约方式: * '''终端操作''':如{{code|reduce()}}、{{code|collect()}}、{{code|min()}}、{{code|max()}}等 * '''可变归约''':通过{{code|Collectors}}工具类实现更复杂的聚合 == 基本归约操作 == === reduce()方法 === {{code|reduce()}}是Stream API中最基础的归约方法,有三种重载形式: <syntaxhighlight lang="java"> // 1. 无初始值版本 Optional<T> reduce(BinaryOperator<T> accumulator) // 2. 有初始值版本 T reduce(T identity, BinaryOperator<T> accumulator) // 3. 并行流优化版本 <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner) </syntaxhighlight> ==== 示例1:求和 ==== <syntaxhighlight lang="java"> List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 无初始值 Optional<Integer> sum1 = numbers.stream().reduce((a, b) -> a + b); System.out.println(sum1.get()); // 输出: 15 // 有初始值 int sum2 = numbers.stream().reduce(0, (a, b) -> a + b); System.out.println(sum2); // 输出: 15 </syntaxhighlight> ==== 示例2:求最大值 ==== <syntaxhighlight lang="java"> Optional<Integer> max = numbers.stream().reduce(Integer::max); System.out.println(max.get()); // 输出: 5 </syntaxhighlight> == 可变归约(Collectors)== 对于更复杂的归约操作,可以使用{{code|Collectors}}工具类: === 常用收集器 === {| class="wikitable" |+ 常见Collectors方法 ! 方法 !! 描述 !! 示例 |- | {{code|toList()}} || 收集到List || {{code|stream.collect(Collectors.toList())}} |- | {{code|joining()}} || 字符串拼接 || {{code|stream.collect(Collectors.joining(", "))}} |- | {{code|summingInt()}} || 整数求和 || {{code|stream.collect(Collectors.summingInt(x -> x))}} |- | {{code|averagingDouble()}} || 求平均值 || {{code|stream.collect(Collectors.averagingDouble(x -> x))}} |} === 示例:复杂归约 === <syntaxhighlight lang="java"> List<String> words = Arrays.asList("Java", "Stream", "API"); // 字符串拼接 String joined = words.stream() .collect(Collectors.joining(", ")); System.out.println(joined); // 输出: Java, Stream, API // 分组统计 Map<Integer, List<String>> lengthMap = words.stream() .collect(Collectors.groupingBy(String::length)); System.out.println(lengthMap); // 输出: {4=[Java], 6=[Stream, API]} </syntaxhighlight> == 并行归约 == Stream API自动支持并行归约,但需要注意: * 累加器(accumulator)和组合器(combiner)必须满足结合律 * 初始值(identity)必须满足:{{math|combiner.apply(identity, x) {{=}} x}} === 并行示例 === <syntaxhighlight lang="java"> int parallelSum = numbers.parallelStream() .reduce(0, (a, b) -> a + b, Integer::sum); System.out.println(parallelSum); // 输出: 15 </syntaxhighlight> == 实际应用案例 == === 案例1:电商订单统计 === 计算订单总金额和平均金额: <syntaxhighlight lang="java"> class Order { String id; double amount; // 构造方法/getters省略 } List<Order> orders = Arrays.asList( new Order("A001", 99.99), new Order("A002", 149.99), new Order("A003", 79.99) ); DoubleSummaryStatistics stats = orders.stream() .collect(Collectors.summarizingDouble(Order::getAmount)); System.out.println("总数: " + stats.getCount()); System.out.println("总和: " + stats.getSum()); System.out.println("平均: " + stats.getAverage()); System.out.println("最大: " + stats.getMax()); System.out.println("最小: " + stats.getMin()); </syntaxhighlight> === 案例2:日志分析 === 统计不同日志级别的出现次数: <syntaxhighlight lang="java"> List<String> logs = Arrays.asList( "ERROR: Disk full", "WARN: Connection timeout", "ERROR: File not found", "INFO: User logged in" ); Map<String, Long> levelCounts = logs.stream() .map(log -> log.split(":")[0]) .collect(Collectors.groupingBy( Function.identity(), Collectors.counting() )); System.out.println(levelCounts); // 输出: {ERROR=2, WARN=1, INFO=1} </syntaxhighlight> == 性能考虑 == * 对于简单归约,{{code|reduce()}}通常比{{code|collect()}}更高效 * 复杂归约应优先使用{{code|Collectors}} * 大数据集考虑使用并行流,但要注意线程安全问题 <mermaid> graph TD A[原始流] --> B[顺序归约] A --> C[并行归约] B --> D[单线程结果] C --> E[多线程合并结果] D & E --> F[最终结果] </mermaid> == 数学基础 == 归约操作在数学上可以表示为: <math> \text{reduce}(f, [a_1, a_2, ..., a_n]) = f(a_1, f(a_2, f(..., f(a_{n-1}, a_n)...))) </math> 其中{{math|f}}是满足结合律的二元操作。 == 常见问题 == === 何时使用reduce() vs collect()? === * 使用{{code|reduce()}}当: * 操作是不可变的(如数值计算) * 不需要中间容器 * 使用{{code|collect()}}当: * 需要可变容器(如集合) * 操作涉及状态累积 === 为什么Optional在无初始值的reduce()中返回? === 因为空流没有有效返回值,Optional明确表示了这种可能为空的情况。 == 总结 == Java Stream归约提供了强大的数据聚合能力: * 简单归约使用{{code|reduce()}} * 复杂归约使用{{code|Collectors}} * 并行流可提高大数据集处理效率 * 遵循函数式编程原则,写出更声明式的代码 通过合理应用归约操作,可以显著简化集合处理代码,提高程序可读性和维护性。 [[Category:编程语言]] [[Category:Java]] [[Category:Java Stream API]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Code
(
编辑
)
模板:Main other
(
编辑
)
模板:Math
(
编辑
)
模板:Math/styles.css
(
编辑
)
模块:Check for unknown parameters
(
编辑
)