集合类关系:
|
|
Collection
java.util.Collection
Collection是List和Set的父接口。它继承了Iterable接口,所以每个Collection的子类应该是可以迭代访问其中的元素的。
我注意到一个有意思的函数,该函数在Java1.8中引入。该函数的功能是从集合中删除所有满足条件的元素,代码实现平平无奇,主要是函数有一个default修饰。Java8提供了default让接口中也可以实现方法体,目的是为了让开发者在给interface添加新方法时,不必再一一修改实现该接口的类,这些类可以使用默认的方法实现。
|
|
Collection的equals
Collection的equals方法的重写需要小心谨慎。简单的使用引用比较还是比较简单安全的,值比较则会变复杂。相等必须是对称的,约定List只能和其它List相等,Set亦然。所以你自己实现的Collection类在和List、Set比较时应该返回false,因为即使你定制的Collection可以返回true,但是从List的视角来比较,返回的是false,不满足对称性。因此,也无法正确的
实现一个既有List接口,又有Set接口的类。
遵照约定,如果你重写了equals方法,那么你要同时重写hashCode方法。c1.equals(c2)成立,则c1.hashCode()==c2.hashCode()。
Spliterator和Stream
Spliterator接口在Java8中引入,这个单词是Split和iterator的合成,用来分割集合以给并行处理提供方便。看个例子:
|
|
运行结果:
|
|
相较于传统的iterator,spliterator可以递归的对集合进行划分,每个spliterator管理了原来集合中的部分元素。但是,每个spliterator并不是线程安全的,所以并行处理时,要保证每一个划分在同一个线程中进行处理。
Collection提供Stream对元素进行流处理,其中用到了spliterator。看个例子:
|
|
结果:
集合经过两步处理,过滤出了所有符合条件的元素。Stream整体处理过程分为两步:1.Configuration,2.Processing。Filter是Configuration,collect是Processing。还可以看出一点,最后获取的结果List是一个新建的List,并不和原List共享内存中的元素。
再看一个reduce的例子:
结果是:45。这是一个求和运算,其中第一个参数0
是acc的初始值,acc表示上一步(acc, item) -> acc + item
的结果,item是每次从stream中取的值。这些Configuration并不立即执行,而是等到最后一个Processing函数,统一执行。
在Collection中有parallelStream提供并行运算,并且使用了默认的spliterator对集合进行划分。例子如下:
|
|
结果:
可见,并行运算无法保证每个元素被处理的顺序。