java结合性是什么东西_java8学习之Collector同一性与结合性分析

继续沿着上一次【http://www.cnblogs.com/webor2006/p/8311074.html】Collector接口的javadoc进行阅读,在继续阅读之前,其中有个比较难理解的地方需要再解释一下,如下:

c9c0429bffdef85a0c4f453dfbd262b1.png

d3df7a559004a19311fd5c001fa1e2c3.png

上面的javadoc描述的到底是怎么一回事呢?下面来好好理解下:

9c6a2b79cd39f6a2b2c0cf416138afdb.png

对于combiner()方法是针对并行流(parallelStream())而言的,既然是并行流,当然是存在多个线程去执行,假设有4个线程,那肯定就会有4个"部份"结果,而这个方法的作用就是将这4个"部份"结果合并成一个,但是!!该方法最终是返回一个BinaryOperator,而它是接收两个同类型的参数并返回一个同类型的结果,所以可能存在以下情况:

对于"线程1结果、线程2结果、线程3结果、线程4结果",合并过程可能是如下:

线程1结果 + 线程2结果 最终合并成 5结果

5结果 + 线程3结果 最终合并成 6结果

6结果 + 线程4结果 最终合并成 7结果

其中“7结果”就是最终我们需要的合并之后的结果,那什么对于"线程1结果 + 线程2结果 最终合并成 5结果",其中javadoc中的"fold state from one argument into the other"也就是指将两个集合合并之后最终添加到另一个集合中,而对于咱们的这种情况很显然是将合并结果放到了一个新生成的结果容器当中了,此时这种情况就对应于javadoc说的这处地方:

d139e0329e5fc5d174d1285f0c691083.png

接下来对于两个部份结果可能还存在这种合并情况:

对于线程1结果、线程2结果,将线程2的结果全部合并添加到线程1结果当中,最后再将线程1的结果返回回来,也就是并非有创建一个新的结果容器了,此时就对应于javadoc说的这种情况:

3c31d506d38a27c150fe0eb57e87a524.png

接下来继续来读Collector接口的javadoc,如下:

4a73e34166b1486c5517f85c009ff880.png

其中Characteristics是一个枚举,如下:

d6f5c4a70cb598f923ba7c1e58b33491.png

153b0f92dd16e4a5d55aeacfa1c1523d.png

f87d33fdf0e12b76188903a99541e853.png

ab4aee8a49c9845e47872a947cc9a7a5.png

d196074e5d7a093ae7c3e70bf58fc6f7.png

关于combiner()函数在开头就已经说明了,其实这句话就是描述咱们解释的这个意思,另外很明显combiner()只是针对并行操作而言的,对于串行操作是用不到combiner()的。

fecf086a18793553852014e47e5f9e1e.png

关于这两个条件下面对其进行了介绍,如下:

91afbc0b0fe33d1a7e7b819193c0dad2.png

还是有些抽象,看下面的进一步解释:

d2f84a0aef06196b6b783fb8fc5bc398.png

那什么"a = combiner.apply(a, supplier.get())"这个等式会成立呢?需要举一个例子来说明一下:

对于combiner()操作是将两个参数合并成一个参数,其Lambda表达式可以用它来表示:

(List list1, List list2) -> { list1.addAll(list2); return list1; }

这属于combiner()中将一个元素折叠到另一个元素并将其返回的情况,以它做为模板,那回到咱们这个等式:

combiner.apply(a, supplier.get())这句说明list1=a、supplier.get()=list2,而由于supplier.get()返回的是一个空的结果容器,就像javadoc中描述的那样:

8b6a56b612eeef81debdbfb31556b29c.png

那执行combiner()函数之后,就会执行combiner.apply(a, supplier.get()) = list1.addAll(list2)=list1.addAll(空的结果容器) = list1= a,刚好等式成立。

接下来看另外一个特性:

a9299d34b479b650c819b5841c2d9311.png

6e083ec9a316efeeb6683a949ac88eaa.png

1ca96c49fddc0161001a6a2406efe2fc.png

f71c269324da0be02bb526f111411242.png

e42597185834efff7036f60d8cf9e251.png

3c8ee09e8228851c17defcdcecaceb3c.png

从这里面可以看出,虽说使用上面来看是简单了,其实这个简单是因为底层将其复杂性给封装起来了。

0f80d7cbda796ced7aa209be211d2489.png

97d7b19fc7b98e317f9d0c5eb4603f72.png

这块暂且有个了解既可,之后还会详细研究的。

37f674af0bccf29548b4d3f06332cb89.png

接下来这个规则就有一大堆英文,所以这个放到下次再学。

从读javadoc中将要点总结如下【跟上次读的一起汇总】:

1、stream.collect()名为收集器。

2、Collector作为collect方法的参数。

3、Collector是一个接口,它是一个可变的汇聚操作,将输入元素累积到一个可变的结果容器中;它会在所有元素都处理完毕之后,将累积的结果转换为一个最终的表示。【这是一个可选的操作】;它支持串行与并行两种方式执行。

4、Collectors本身提供了关于Collector的常见汇聚实现,Collectors本身实际上是一个工厂。【在之后也会研读它里面的源码滴】

5、为了确保串行与并行操作结果的等价性,Collector函数需要满足两个条件:identity(同一性) 与 associativty(结合性)。

6、a = combiner.apply(a, supplier.get())。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值