方法引用 Number::getValue 可以用下面的 lambda 表达式替换 。参数 n 是流中的 Number 实例中的之一:
mapToInt(n -> n.getValue()) 通常,lambda 表达式和方法引用是可互换的:如果像 mapToInt 这样的高阶函数可以采用一种形式作为参数,那么这个函数也可以采用另一种形式 。这两个函数式编程结构具有相同的目的 —— 对作为参数传入的数据执行一些自定义操作 。在两者之间进行选择通常是为了方便 。例如,lambda 可以在没有封装类的情况下编写,而方法则不能 。我的习惯是使用 lambda,除非已经有了适当的封装方法 。
当前示例末尾的 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) -> sofarnext);// 求和 此版本的 reduce 函数带有两个参数,第二个参数是一个函数:
第一个参数(在这种情况下为零)是特征值,该值用作求和操作的初始值,并且在求和过程中流结束时用作默认值 。第二个参数是累加器,在本例中,这个 lambda 表达式有两个参数:第一个参数(sofar)是正在运行的和,第二个参数(next)是来自流的下一个值 。运行的和以及下一个值相加,然后更新累加器 。请记住,由于开始时调用了 parallelStream,因此 map 和 reduce 函数现在都在多线程上下文中执行 。在到目前为止的示例中,流值被收集,然后被规约,但是,通常情况下,流 API 中的 Collectors 可以累积值,而不需要将它们规约到单个值 。正如下一个代码段所示,收集活动可以生成任意丰富的数据结构 。该示例使用与前面示例相同的 listOfNums:
Map> numMap = listOfNums.parallelStream().collect(Collectors.groupingBy(Number::getParity));List evens = numMap.get(Number.Parity.EVEN);List odds = numMap.get(Number.Parity.ODD); 第一行中的 numMap 指的是一个 Map,它的键是一个 Number 奇偶校验位(ODD 或 EVEN),其值是一个具有指定奇偶校验位值的 Number 实例的 List 。同样,通过 parallelStream 调用进行多线程处理,然后 collect 调用(以线程安全的方式)将部分结果组装到 numMap 引用的 Map 中 。然后,在 numMap 上调用 get 方法两次,一次获取 evens,第二次获取 odds 。
猜你喜欢
- 教你使用这两个excel自动排名函数 excel按分数高低排序怎么排
- believe in的用法解析 believein
- 解析void函数应用 void函数已有主体怎么解决
- 似shi和si的用法 似的多音字
- apply的用法和搭配 call和apply的区别是什么
- Excel做复利终值系数表 excel复利计算函数
- 初中二次函数的图象与性质 二次函数判别式的意义
- left函数用法与理解 left函数
- 常用函数汇总学习 mysql绝对值函数
- java字符串截取方法 java字符串分割函数
