《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一1.12 约简操作

简介: 本节书摘来华章计算机《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一书中的第1章 ,第1.12节,[美] 凯S.霍斯特曼(Cay S. Horstmann) 著陈昊鹏 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.12 约简操作

reduce方法是一种用于从流中计算某个值的通用机制,其最简单的形式将接受一个二元函数,并从前两个元素开始持续应用它。如果该函数是求和函数,那么就很容易解释这种机制:
image

在上面的情况中,reduce方法会计算v0+v1+v2+…,其中vi是流中的元素。如果流为空,那么该方法会返回一个Optional,因为没有任何有效的结果。

注意:在上面的情况中,可以写成reduce(Integer::sum)而不是reduce((x, y) -> x+y)。

通常,如果reduce方法有一项约简操作op,那么该约简就会产生v0 op v1 op v2 op…,其中我们将函数调用op(vi, vi+1)写作vi op vi+1。这项操作应该是可结合的:即组合元素时使用的顺序不应该成为问题。在数学标记法中,(x op y) op z必须等于x op (y op z)。这使得在使用并行流时,可以执行高效的约简。
有很多种在实践中会显得很有用的可结合操作,例如求和、乘积、字符串连接、取最大值和最小值、求集的并与交等。减法是一个不可结合操作的例子,例如,(6-3)-2≠6-(3-2)。
通常,会有一个幺元值e使得e op x = x,可以使用这个元素作为计算的起点。例如,0是加法的幺元值。然后,可以调用第2种形式的reduce:
image

如果流为空,则会返回幺元值,你就再也不需要处理Optional类了。
现在,假设你有一个对象流,并且想要对某些属性求和,例如字符串流中的所有字符串的长度,那么你就不能使用简单形式的reduce,而是需要(T,T)->T这样的函数,即引元和结果的类型相同的函数。但是在这种情况下,你有两种类型:流的元素具有String类型,而累积结果是整数。有一种形式的reduce可以处理这种情况。
首先,你需要提供一种“累积器”函数(total, word) -> total + word.length()。这个函数会被反复调用,产生累积的总和。但是,当计算被并行化时,会有多个这种类型的计算,你需要将它们的结果合并。因此,你需要提供第二个函数来执行此处理。完整的调用如下:
image

注意:在实践中,你可能并不会频繁地用到reduce方法。通常,映射为数字流并使用其方法来计算总和、最大值和最小值会更容易。(我们将在1.13节中讨论数字流。)在这个特定示例中,你可以调用words.mapToInt(String::length).sum(),因为它不涉及装箱操作,所以更简单也更高效。
注意:有时reduce会显得并不够通用。例如,假设我们想要收集BitSet中的结果。如果收集操作是并行的,那么就不能直接将元素放到单个BitSet中,因为BitSet对象不是线程安全的。因此,我们不能使用reduce,因为每个部分都需要以其自己的空集开始,并且reduce只能让我们提供一个幺元值。此时,应该使用collect,它会接受单个引元:

1.一个提供者,它会创建目标类型的新实例,例如散列集的构造器。
2.一个累积器,它会将一个元素添加到一个实例上,例如add方法。
3.一个组合器,它会将两个实例合并成一个,例如addAll。
下面的代码展示了collect方法是如何操作位集的:

image

java.util.Stream 8
image

相关文章
|
3月前
|
Java BI 数据处理
如何在Java中实现Excel操作
如何在Java中实现Excel操作
|
3月前
|
存储 Java 索引
Java ArrayList操作指南:如何移除并返回第一个元素
通过上述方法,你可以方便地从Java的 `ArrayList` 中移除并返回第一个元素。这种操作在日常编程中非常常见,是处理列表时的基本技能之一。希望这篇指南能帮助你更好地理解和运用Java的 `ArrayList`。
39 4
|
3月前
|
分布式计算 DataWorks Java
DataWorks操作报错合集之使用ODPS Tunnel Upload功能时,遇到报错:Java 堆内存不足,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
3月前
|
SQL 缓存 Java
使用MyBatis优化Java持久层操作
使用MyBatis优化Java持久层操作
|
3月前
|
Java API 开发者
Java中的文件I/O操作详解
Java中的文件I/O操作详解
|
3月前
|
Java BI 数据处理
如何在Java中实现Excel操作
如何在Java中实现Excel操作
|
3月前
|
并行计算 Java 数据挖掘
Java面试题:解释Java中的Stream API及其操作
Java面试题:解释Java中的Stream API及其操作
39 0
|
3月前
|
SQL 缓存 Java
使用MyBatis优化Java持久层操作
使用MyBatis优化Java持久层操作
|
3月前
|
存储 缓存 安全
Java List操作详解及常用方法
Java List操作详解及常用方法
|
3月前
|
Java API 开发者
Java中不同I/O操作的性能比较
Java中不同I/O操作的性能比较
下一篇
无影云桌面