http://docs.oracle.com/javase/6/docs/technotes/guides/collections/overview.html
集合框架层次上比较复杂,网上有无数文字和图片来说明,这里按我的思路整理了一下:
省略了AbstractCollection,AbstractList等层次的抽象类
省略了RoleList等javax包中的应用方向的实现
省略了Vector,Stack,HashTable这些著名的老家伙。
按照我的一般认识进行归类,例如LinkedList同时实现了Deque和List,这里归入List中;再例如Deque本应继承自Queue,但这里放在同一个级别上。
一切都是为了尽可能建立一个较清晰的第一印象,知道该在什么场景下使用什么类。
-------------------------------------------------
Collection 集合接口(传统包util)
Queue 队列
PriorityQueue 无界优先级队列
Deque 双端队列
ArrayDeque 基于数组的无界双端队列,做队列和栈都很合适
List 有序集合
ArrayList 基于数组的有序集合
LinkedList 基于链表的有序结合(其实也是一个Deque)
Set
EnumSet 枚举专用的set,效率高
HashSet 基本的快速哈希Set,基于HashMap
LinkedHashSet 附加了链表的哈希Set,插入慢,迭代快,有序
TreeSet 插入时就维持顺序,基于TreeMap实现,可快速获取子集
总结:
栈和队列,用ArrayDeque或者linkedList(各有千秋);其余类的适应范围都比较明确。
-------------------------------------------------
Collection 集合接口(并发包concurrent)
Queue 队列
ConcurrentLinkedQueue 基于链接节点的无界线程安全队列
BlockingQueue 阻塞队列
ArrayBlockingQueue 基于数组的有界阻塞队列
DelayQueue 无界阻塞队列,只有在延迟期满时才能从中提取元素
LinkedBlockingQueue 基于链表的无界阻塞队列
PriorityBlockingQueue 带优先级的无界阻塞队列
SynchronousQueue 无容量的同步队列,两个线程插入与移除交替进行
Deque 双端队列
BlockingDeque 阻塞双端队列
LinkedBlockingDeque 基于链表的阻塞双端队列
List 有序集合
CopyOnWriteArrayList 可变操作通过底层复制来实现,适合多读取,少修改
Set
ConcurrentSkipListSet 多线程可以安全地发执行各种操作,迭代器弱一致
CopyOnWriteArraySet 可变操作通过底层复制来实现,适合多读取,少修改
总结:
1,ConcurrentLinkedQueue与LinkedBlockingQueue:
http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html#ixzz1seaiSLwp
如果生产者与消费者的关系是“多对多”,选LinkedBlockingQueue(阻塞方式)要快很多,代价是迭代遍历的效率奇低。
如果生产者与消费者的关系是“一对多”或者“多对一”,选ConcurrentLinkedQueue(无等待方式)会有一定性能提升。
2,ArrayBlockingQueue比LinkedBlockingQueue的表现更稳定和更可预测,但是后者的吞吐量往往更高。
3,List:
CopyOnWriteArrayList貌似只适合“多读取,少写入”的场景,其余情况还是乖乖的Collections.synchronizedList()吧。
4,Set:
ConcurrentSkipListSet可以当作并发版的TreeSet。
CopyOnWriteArraySet可以当作并发版的linkedHashSet,适合多读取,少修改。
奇怪的是java没有提供ConcurrentHashSet,按理说基于ConcurrentHashMap可以实现的。
读写都频繁的同步Set只能凑合了,用ConcurrentSkipListSet可能比synchronizedSet要强?
http://dhruba.name/2009/08/05/concurrent-set-implementations-in-java-6/
按上面的链接说法,可以试试这个:
Collections.newSetFromMap(new ConcurrentHashMap<Object,Boolean>())
Use this when you have large sets, a good (and fast) hash function and can estimate the set size and needed concurrency before creating the map.
-------------------------------------------------
Map 映射接口 (传统包util)
EnumMap 枚举专用的map,效率高
HashMap 基本的快速哈希表
LinkedHashMap 附加了链表的哈希表,插入慢,迭代快,有序
IdentityHashMap 实现中用“==”运算代替“equals()”作为判断键和值是否相等
TreeMap 基于红黑树,插入时就维持顺序,可快速获取子集
WeakHashMap 以“弱键”实现,其中的键可能会被垃圾回收,导致此映射被移除
-------------------------------------------------
Map 映射接口 (并发包concurrent)
ConcurrentMap
ConcurrentHashMap
ConcurrentSkipListMap
总结:
ConcurrentHashMap可以当作并发版的HashMap
ConcurrentSkipListMap可以当作并发版的TreeMap
-------------------------------------------------
How to choose which Java collection class to use?
http://www.javamex.com/tutorials/collections/how_to_choose_2.shtml
the Queue interface
http://www.javamex.com/tutorials/synchronization_concurrency_8_queues_2.shtml
-------------------------------------------------
吐槽:不知道“基于数组的无界双端队列”这句话中的“无界”会不会被敏感掉,想起了“十六嘴交换机”的故事。