在Java的Collections API中,不狭义的区分语法上的接口和类,把它们都看作是类的话,大致我们可以发现三种主要的类别:
1- 容器类:如Collection、List、Map等,用于存放对象和进行简单操作的;
2- 操作类:如Collections、Arrays等,用于对容器类的实例进行相对复杂操作如排序等;
3- 辅助类:如Iterator、Comparator等,用于辅助操作类以及外部调用代码实现对容器类的操作,所谓辅助,概括而通俗的来讲,就是这些类提供一种算法,你给它一个对象或者一组对象,或者仅仅是按一定的规则调用它,它给你一个运算后的答案,帮助你正确处理容器对象。比如Iterator会告诉你容器中下一个对象有没有、是什么,而Comparator将对象大小/先后次序的算法逻辑独立出来。
对于这样的一个大包,当然不可能一个类一个类的讲了,找一些常用的和有用的当做学习的阶段(不分轻重)。大概列个清单:
Bag
HashBag
BagUtils
--------------------------
Buffer
BlockingBuffer
BoundedFifoBuffer
PriorityBuffer
BufferUtils
--------------------------
MultiMap
BidiMap
CaseInsensitiveMap
LazyMap
MapUtils
--------------------------
TypedCollection
CollectionUtils
--------------------------
ReverseComparator
ComparatorChain
NullComparator
FixedOrderComparator
ComparatorUtils
--------------------------
Predicate
AndPredicate
OrPredicate
AllPredicate
OnePredicate
NonePredicate
PredicateUtils
--------------------------
Transformer
ChainedTransformer
SwitchTransformer
TransformerUtils
--------------------------
Closure
ChainedClosure
IfClosure
WhileClosure
ClosureUtils
--------------------------
LoopingIterator
ArrayListIterator
FilterIterator
UniqueFilterIterator
IteratorUtils
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
学习之第一组:
Bag
HashBag
BagUtils
Bag是在org.apache.commons.collections包中定义的接口,它extends java.util.Collection,而它的实现类都被放在下面的bag包中。之所以有这样一组类型,是因为我们有时候需要在Collection中存放多个相同对象的拷贝,并且需要很方便的取得该对象拷贝的个数。需要注意的一点是它虽然extends Collection,但是如果真把它完全当作java.util.Collection来用会遇到语义上的问题,详细信息参考Javadoc。
HashBag是Bag接口的一个标准实现。而BagUtils提供一组static的方法让调用者获取经过不同装饰后的Bag实例
学习之第二组:
Buffer
BlockingBuffer
BoundedFifoBuffer
PriorityBuffer
UnboundedFifoBuffer
BufferUtils
Buffer是定义在org.apache.commons.collections包下面的接口,用于表示按一定顺序除去成员对象的collection如队列等。具体的实现类在org.apache.commons.collections.buffer包下可以找到。
BufferUtils提供很多静态/工具方法装饰现有的Buffer实例,如将其装饰成BlockingBuffer、执行类型检查的TypedBuffer、或者不可改变的UnmodifiableBuffer等等。
最简单直接的Buffer实现类是UnboundedFifoBuffer,提供先进先出的大小可变的队列。
而BoundedFifoBuffer则是对其大小进行了限制,是固定大小的先进先出队列。
BlockingBuffer要在多线程的环境中才能体现出它的价值,尤其是当我们需要实现某种流水线时这个BlockingBuffer很有用:每个流水线上的组件从上游的BlockingBuffer获取数据,处理后放到下一个BlockingBuffer中依次传递。BlockingBuffer的核心特色通俗点说就是如果你向它要东西,而它暂时还没有的话,你可以一直等待直至拿到为止。
PriorityBuffer则提供比一般的先进先出Buffer更强的控制力:我们可以自定义Comparator给它,告诉它怎么判定它的成员的先后顺序,优先级最高的最先走。、
Buffer的add和remove方法分别添加新成员和删除最先加入的成员。
由于我们的Buffer定义为只能装3个Book类的实例,所以不论我们试图加入其他类型的对象,或者加入超过3个,操作都将失败。
如果我们在遍历时使用get()而不调用remove(),那么我们将得到3个相同的拷贝,而这正是我们期望的FIFO队列的行为。
假如你需要遍历并保留数据,可以使用标准的Iterator机制。
下面我们验证下上述的第二条:
学习之第三组:
BidiMap
MultiMap
LazyMap
MapUtils
所谓BidiMap,直译就是双向Map,可以通过key找到value,也可以通过value找到key,这在我们日常的代码-名称匹配的时候很方便:因为我们除了需要通过代码找到名称之外,往往也需要处理用户输入的名称,然后获取其代码。需要注意的是BidiMap当中不光key不能重复,value也不可以。
所谓MultiMap,就是说一个key不在是简单的指向一个对象,而是一组对象,add()和remove()的时候跟普通的Map无异,只是在get()时返回一个Collection,利用MultiMap,我们就可以很方便的往一个key上放数量不定的对象,也就实现了一对多。
所谓LazyMap,意思就是这个Map中的键/值对一开始并不存在,当被调用到时才创建,这样的解释初听上去是不是有点不可思议?这样的LazyMap有用吗?我们这样来理解:我们需要一个Map,但是由于创建成员的方法很“重”(比如数据库访问),或者我们只有在调用get()时才知道如何创建,或者Map中出现的可能性很多很多,我们无法在get()之前添加所有可能出现的键/值对,或者任何其它解释得通的原因,我们觉得没有必要去初始化一个Map而又希望它可以在必要时自动处理数据生成的话,LazyMap就变得很有用了。
map迭代
jdk中的map接口很难进行迭代。api用户总是需要通过entryset或者keyset进行迭代。commons-collectons现在提供了一个新的接口—mapiterator来允许对maps进行简单的迭代。
BeanMap(已过时)
将bean 和map间进行转换
学习之第四组:
TypedCollection
CollectionUtils
// 并集
Collection unionList = CollectionUtils.union(aList, bList);
// 交集
Collection intersectionList = CollectionUtils.intersection(aList, bList);
// 是否存在交集
booleanisContained = CollectionUtils.containsAny(aList, bList);
// 交集的补集
Collection disjunctionList = CollectionUtils.disjunction(aList, bList);
// 集合相减
Collection subtractList = CollectionUtils.subtract(aList, bList);
// 排序
Collections.sort((List) unionList);
// 查询
Collections.select(Collection inputCollection, Predicate predicate) //返回符合条件的 集合
官方解释:将与给定谓词匹配的输入集合中的所有元素选择为输出集合。
(额外分享1:jdk中的collections下的copy方法:
官方注释:复制所有的元素从一个表到另一个。操作之后,目标列表中每个复制元素的索引将与源列表中的索引相同。目标列表必须至少与源列表一样长。如果时间较长,目标列表中的其余元素不受影响。
额外分享2:依次移除 list 中的元素。
结果:
解决方案:
)