当前示例末尾的 sum 函数通过结合来自 parallelStream 线程的部分和,以线程安全的方式进行归约 。但是,程序员有责任确保在 parallelStream 调用引发的多线程过程中,程序员自己的函数调用(在本例中为 getValue)是线程安全的 。
最后一点值得强调 。lambda 语法鼓励编写 纯函数(pure function),即函数的返回值仅取决于传入的参数(如果有);纯函数没有副作用,例如更新一个类中的 static 字段 。因此,纯函数是线程安全的,并且如果传递给高阶函数的函数参数(例如 filter 和 map )是纯函数,则流 API 效果最佳 。
对于更细粒度的控制,有另一个流 API 函数,名为 reduce,可用于对 Number 流中的值求和:
Integer sum4AllHarder = listOfNums .parallelStream() // 多线程 .map(Number::getValue) // 每个 Number 的值 .reduce(0, (sofar, next) -> sofar + next); // 求和
此版本的 reduce 函数带有两个参数,第二个参数是一个函数:
- 第一个参数(在这种情况下为零)是特征值,该值用作求和操作的初始值,并且在求和过程中流结束时用作默认值 。
- 第二个参数是累加器,在本例中,这个 lambda 表达式有两个参数:第一个参数(sofar)是正在运行的和,第二个参数(next)是来自流的下一个值 。运行的和以及下一个值相加,然后更新累加器 。请记住,由于开始时调用了 parallelStream,因此 map 和 reduce 函数现在都在多线程上下文中执行 。
Map<Number.Parity, List<Number>> numMap = listOfNums .parallelStream() .collect(Collectors.groupingBy(Number::getParity));List<Number> evens = numMap.get(Number.Parity.EVEN);List<Number> odds = numMap.get(Number.Parity.ODD);
第一行中的 numMap 指的是一个 Map,它的键是一个 Number 奇偶校验位(ODD 或 EVEN),其值是一个具有指定奇偶校验位值的 Number 实例的 List 。同样,通过 parallelStream 调用进行多线程处理,然后 collect 调用(以线程安全的方式)将部分结果组装到 numMap 引用的 Map 中 。然后,在 numMap 上调用 get 方法两次,一次获取 evens,第二次获取 odds 。实用函数 dumpList 再次使用来自流 API 的高阶 forEach 函数:
private void dumpList(String msg, List<Number> list) { System.out.println("\n" + msg); list.stream().forEach(n -> n.dump()); // 或者使用 forEach(Number::dump)}
这是示例运行中程序输出的一部分:The sum of the randomly generated values is: 3322The sum again, using a different method: 3322Evens:Value: 72 (parity: even)Value: 54 (parity: even)...Value: 92 (parity: even)Odds:Value: 35 (parity: odd)Value: 37 (parity: odd)...Value: 41 (parity: odd)
用于代码简化的函数式结构函数式结构(如方法引用和 lambda 表达式)非常适合在流 API 中使用 。这些构造代表了 Java 中对高阶函数的主要简化 。即使在糟糕的过去,Java 也通过 Method 和 Constructor 类型在技术上支持高阶函数,这些类型的实例可以作为参数传递给其它函数 。由于其复杂性,这些类型在生产级 Java 中很少使用 。例如,调用 Method 需要对象引用(如果方法是非静态的)或至少一个类标识符(如果方法是静态的) 。然后,被调用的 Method 的参数作为对象实例传递给它,如果没有发生多态(那会出现另一种复杂性!),则可能需要显式向下转换 。相比之下,lambda 和方法引用很容易作为参数传递给其它函数 。
推荐阅读
- c语言退出程序命令exit c语言exit函数用法
- 矩阵所有元素求和的公式 matlab矩阵求和函数
- c语言圆的面积编程 c语言阶乘函数怎么写
- 同位语从句经典例句 求同位语的具体用法和例句分析。
- spend的用法
- 并列连词 并列连词与从属连词的用法区别?
- 《如龙:极》鬼炎用法技巧解析攻略
- 对马岛之魂辅助功能有什么 对马之魂辅助功能用法介绍
- 团战经理骑士怎么用 团战经理骑士用法详解
- 团战经理狙击手好用吗 团战经理狙击手用法介绍