《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

相关文章
|
2月前
|
开发框架 Java API
最新Java基础系列课程--Day13-高级特性(二)
最新Java基础系列课程--Day13-高级特性
|
2月前
|
消息中间件 Java
Java操作RabbitMQ单一生产-消费者模式
Java操作RabbitMQ单一生产-消费者模式
24 0
|
2天前
|
存储 Java 数据处理
|
24天前
|
存储 Java
java Map集合相关介绍和方法使用操作
java Map集合相关介绍和方法使用操作
19 2
|
24天前
|
存储 Java
java set集合相关介绍和方法使用操作
java set集合相关介绍和方法使用操作
16 2
|
24天前
|
存储 Java 索引
java list集合相关介绍和方法使用操作
java list集合相关介绍和方法使用操作
16 1
|
25天前
|
存储 Java 程序员
Java数组全套深入探究——基础知识阶段3、数组下标操作
Java数组全套深入探究——基础知识阶段3、数组下标操作
12 0
|
25天前
|
网络协议 Java
Java——InetAddress操作
Java——InetAddress操作
5 0
|
1月前
|
JavaScript IDE Java
【操作宝典】IDE神器解密:IntelliJ IDEA详细教程,Java编程进阶指南!
【操作宝典】IDE神器解密:IntelliJ IDEA详细教程,Java编程进阶指南!
31 0
|
2月前
|
SQL 分布式计算 Java
Java Stream 相关操作
Java Stream 相关操作
10 0