reduce-归约

看下词典翻译:
好的命名是自解释的
reduce的方法取得就是其中归纳的含义
java8 流相关的操作中,我们把它理解 "累加器",之所以加引号是因为他并不仅仅是加法
他的运算可以是一个Lambda 表达式
所以更准确的说 reduce 是一个迭代运算器
Stream包的文档中其实已经说的很明白了
但是就是因为不是很理解所以看的云里雾里
其中说到:
一个reduce操作(也称为折叠)接受一系列的输入元素,并通过重复应用操作将它们组合成一个简单的结果
参照reduce方法文档给出的示例

T result = identity;

for (T element : this stream)

result = accumulator.apply(result, element)

return result;

累计运算的概念

以下面的这个方法为例解析
BinaryOperator 是BiFunction 的三参数特殊化形式,两个入参和返回结果都是类型T
计算1,2,3,4,5 的和,并且初始值为3  
也就是计算3+1+2+3+4+5 
1.使用Stream 两个参数的reduce方法进行归约运算
2.使用for循环迭代调用BinaryOperator 的apply进行运算
其实两种方式背后的思维方式是一样的
那就是   
结果重新作为一个参数,不断地参与到运算之中,直到最后结束
理解reduce的含义重点就在于理解"累   加   器" 的概念
只要能够理解了累计运算的概念
就可以完全理解Stream 中reduce方法
他就是一个不断累计运算的过程
Stream的一个参数和两个参数的方法的基本逻辑都是如此
差别仅仅在于一个参数的是result  R = T1 ,然后再继续与剩下的元素参与运算

三个参数的reduce


    <U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

它的形式类似于
与两个参数的reduce不同的地方在于类型
双参数的返回类型为T  Stream类型为T
三参数的返回类型为U  Stream类型为T   有了更大的发挥空间  T可能为U 也可能不是U 
很显然,三参数的reduce 方法的思维方式同双参数的并无二致
所以问题来了,那还要第三个参数做什么?

其实第三个参数用于在并行计算下 合并各个线程的计算结果
并行流运行时:内部使用了fork-join框架
多线程时,多个线程同时参与运算
多个线程执行任务,必然会产生多个结果
那么如何将他们进行正确的合并
这就是第三个参数的作用

大致处理流程

从流程上看的 结果R是一直参与运算的!!
我们之前也有一个例子
两种情况下的结果是不一样的!!!!
结果不同  是因为  ((((5+1)+2)+3)+4)+5   和   (5+1)+ (5+2)+ (5+3)+ (5+4)+ (5+5)  运算结果不相同 

那么这个方法不是有问题么?
其实不然,有问题的是我们的写法
文档中进行了明确的说明要求
翻译下:
第一点:identity 的值对于合并运算combiner来说必须是一个恒等式,也就是说对于任意的u,  combiner(identity,u)  和u是相同的
这句话看起来怪怪的,对于任意的u 经过合并运算 竟然还是u,那还要这个干嘛??
从我们上面的并行处理流程可以看得出来,这个result 的初始identity 对于每一个分支都是参与运算的!
这也是为什么要求:
任意的u,  combiner(identity,u)  和u是相同的
的原因
我们之所以会错,就是因为没有达到要求  
我们的combiner为   (a,b)->a+b;
那么如果分为两个分支进行运算,我们的初始值identity就参与了两次运算  也就是说多加了两个identity的值!!
怎么样才能保证u = combiner(identity,u)  
除非identity=0  这才是对于  (a,b)->a+b  来说能够保障u = combiner(identity,u)    
否则,你就不要用(a,b)->a+b  这个combiner
我们把Identity换成0之后
结果就不再有问题了
第二点
combiner 必须和accumulator要兼容
对于任意的u 和 t
这到底是什么意思呢?
场景
假设说4个元素 1,2,3,4  需要运算
此时假设已经 1,2,3 三组数据已经运算结束,马上要同第四组运算 
如果是并行,我们假定1,2,3 在一个分支   4单独在另一分支
并行时
U为已经计算好的1,2,3后的结果     接下来要与另一组的4 合并
T4则是identity与T参与运算
上面的图就是
combiner.apply(u, accumulator.apply(identity, t))
非并行运算
u 直接与下一个元素进行结合运算

显然这只是并行和非并行两种不同的处理运算方式,他们应该是相同的
也就是

转载于:https://www.cnblogs.com/noteless/p/9511407.html

[五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用...相关推荐

  1. java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

    java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

  2. Java函数式编程(Lambda表达式、Stream流用法)

    函数式编程 1.函数式编程思想 1.1.1 概念 ​ 面向对象思想需要关注用什么对象完成什么事情.而函数式编程思想就类似于我们数学中的函数.它主要关注的是对数据进行了什么操作. 1.1.2 优点 代码 ...

  3. Java并发编程(06):Lock机制下API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Lock体系结构 1.基础接口简介 Lock加锁相关结构中涉及两个使用广泛的基础API:ReentrantLock类和Condition接 ...

  4. java8 四大函数式接口 和 用于数据处理的 stream流 使用详解

    文章目录 Stream 使用示例 四大函数式接口 Function 功能型接口 Consumer 消费型接口 Supplier 提供型接口 Predicate 断言型接口 常用 api stream, ...

  5. Java网络编程实现文件上传和下载案例详解

    客户端: 文件上传案例的客户端:读取本地文件,上传到服务器,读取服务器回写的数据 明确: 数据源:c:\1.jpg 目的地:服务器 实现步骤: 1.创建一个本地字节输入流FileInputStream ...

  6. Java基础--String类底层实现原理及API示例详解

  7. 《深入理解Java函数式编程》系列文章

    Introduction 本系列文将帮助你理解Java函数式编程的用法.原理. 本文受启发于JavaOne 2016关于Lambda表达式的相关主题演讲Lambdas and Functional P ...

  8. 负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础

    负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负 ...

  9. java同步方法完成案例_Java同步代码块和同步方法原理与应用案例详解

    本文实例讲述了java同步代码块和同步方法.分享给大家供大家参考,具体如下: 一 点睛 所谓原子性WOmoad:一段代码要么执行,要么不执行,不存在执行一部分被中断的情况.言外之意是这段代码就像原子一 ...

最新文章

  1. 经理=PD + Architect + PM + HR
  2. SQLServer中ISNULL、NULLIF和CONVERT函数
  3. c++ 函数返回引用
  4. SQL 性能优化梳理,干掉慢SQL!
  5. 2016全球数据新闻奖(DJA)颁布, 12个获奖作品全剖析
  6. java swing 组件技术(上)
  7. 4个变量取最大值 c++_DNF:安徒恩上线服务器爆满,甲板上全是火山C,通关翻出4个金牌...
  8. 关于机器学习,你应该至少学习这8个落地案例|干货集锦
  9. mac lion 安装 mysql_mac osx下安装mysql
  10. MySQL数据库恢复(使用mysqlbinlog命令)
  11. java 修改 referer_看好你的门-客户端传数据-用java修改referer
  12. 【转】HDC,CDC,CWindowDC,CClientDC,CPaintDC等等
  13. java有用还是c有用_这周的有用资源
  14. Via OpenCv Snake算法
  15. 【web前端技术】dicebear一句话生成头像
  16. 关于cocos2d引擎写的手游加速
  17. 机器学习--PCA(主成分分析)
  18. LeetCode | 0665. Non-decreasing Array非递减数列【Python】
  19. 小程序 canvas 绘制图片
  20. Oracle 11g Release 1 (11.1) 单行函数——(返回字符值)字符函数

热门文章

  1. Java方法02 递归
  2. mysql 查询列表是否关注_点赞功能,用mysql还是redis?
  3. linux rc文件是什么,linux通常使用的 rc 和 .(点)文件
  4. 计算机基础术语巧记,报考28个专业术语,你都知道吗?掌握这些才算入门!
  5. f函数java_Java流:对N-1个元素执行f(),对N个元素执行g(),即,最后一个元素使用不同的函数...
  6. 数据结构折半查找例题_数据结构第9章例题与答案
  7. 简述java异常机制处理,简述Java中的异常处理机制
  8. 安卓第二阶段实训预备案例:访问媒体库音频数据
  9. Specificity考量
  10. php 获取图片的宽高,JS怎么获取图片当前宽高