Set
- 通用实现
HashSet比TreeSet更快,但不能保证元素的有序性。如果需要有序性的话,需要使用SortedSet。如果要求按元素值顺序迭代的话,使用TreeSet。绝大多数情况下,只需要使用HashSet就可以了。LinkedHashSet介于HashSet和TreeSet之间,链表运行于哈希表之上,以插入顺序迭代。
HashSet的迭代是线性增长的,同元素的数量和容量有关。容量如果太大的话,会浪费空间和时间;如果太小的话,每一次则会强制增加容量,浪费复制数据结构的时间。因此,一般设置为你希望容量增长到的两倍大小。
- 特殊实现
EnumSet是枚举类型的高性能Set实现。枚举Set的所有成员必须属于同一枚举类型。在内部,它由一个位向量表示,通常是一个long类型的变量维护所有枚举值。
CopyOnWriteArraySet是一个copy-on-write数组实现。例如add,set和remove这些可改变集合的操作都会建立在一个备份数组之上,这些操作是线程安全的,而迭代和查询操作是基于快照缓存数组。即使迭代的过程中,也可以安全的并发插入和删除操作,因为迭代的是快照缓存数组。一般用于少量修改,但频繁迭代的场景。它非常适合用于维护必须防止重复的事件处理列表。
List
- 通用实现
有两种通用实现,分别是ArrayList和LinkedList,ArrayList提供了常量时间的位置访问,当他移动多个元素时,不需要借助额外的对象,可以直接利用System.arraycopy。如果频繁在列表开始位置插入元素,或者迭代的删除元素,这时应该选择LinkedList。这些操作对于LinkedList需要常量时间,而ArrayList则需要线性时间。但位置访问对于LinkedList则是线性时间。因此,一般在选择LinkedList时,最好进行性能测试,否则,选择ArrayList应该是最佳方案。
- 特殊实现
CopyOnWriteArrayList类似于CopyOnWriteArraySet,可变操作时不需要同步,是线程安全的。
Map
- 通用实现
基于key顺序的迭代可以选择TreeMap;如果对速度要求较高,但对于迭代的顺序没有要求的话,可以选择HashMap。如果想要接近HashMap的速度,以插入顺序迭代的话,可以选择LinkedHashMap。LinkedHashMap可以借助removeEldestEntry方法,提供一种自动删除过时映射的策略,这一功能可以用于缓存实现。
- 特殊实现
EnumMap在内部实现是一个数组,它结合了Map接口的安全性和丰富性,以及数组的高效性。如果你需要映射一个Enum到值,可以选择EnumMap实现。
WeakHashMap储存对其key的弱引用。当其key在WeakHashMap外部没有引用时,键值对会被垃圾回收。非常适合用于注册表类型的数据结构。
IdentityHashMap基于标识的哈希表。用于拓扑对象图的转换,例如序列号和深度复制。
- 并发实现
ConcurrentHashMap提供一系列原子操作,如putIfAbsent, remove, 和 replace。高性能、高并发,此实现在执行查询时从不阻塞,并允许客户端选择更新的并发级别。
Queue
- 通用实现
LinkedList实现了Queue接口,提供了FIFO操作。
PriorityQueue是基于最小堆数据结构,可以在构造时指定Comparator或者按照自然顺序排序。优先队列有最大优先队列和最小优先队列,分别由最大堆和最小堆实现。其中,最大优先队列可用于如共享计算机系统的作业调度,当一个作业完成或中断,则获取优先级最高的作业执行;最小优先队列可用于基于时间驱动的模拟器,每一个节点代表一个时间,key就是时间,事件的执行按照时间顺序模拟。
- 并发实现
LinkedBlockingQueue一个可选边界的FIFO阻塞队列,基于链表。若未设置容量,默认为Integer.MAX_VALUE。
ArrayBlockingQueue一个有限边界的FIFO阻塞队列,基于循环数组。
PriorityBlockingQueue一个无边界限定的阻塞优先队列,基于最小堆。
DelayQueue一个时间调度队列,基于优先队列。
SynchronousQueue使用BlockingQueue接口的简单集合机制。一个同步队列内部没有任何容量。每一个插入操作都要等待另一个线程的移除操作;反之亦然。非常适合于切换设计,在一个线程中运行的对象必须与在另一个线程中运行的对象同步,以便传递一些信息、事件或任务。
在JDK 7中,TransferQueue是一类BlockingQueue的特殊实现。向队列添加元素可以选择阻塞,用于其他线程查询这个元素。LinkedTransferQueue是一个无边界的TransferQueue,基于链表。
Deque
- 通用实现
ArrayDeque是可调整数组的Deque接口实现,而LinkedList是列表实现。LinkedList比ArrayDeque更灵活,其元素支持null。而从效率考虑,ArrayDeque更优。
- 并发实现
LinkedBlockingDeque是Deque接口的并发实现。
包装实现
也就是实现了装饰器模式。为指定的Collection增加一些额外的功能。这些实现由Collections的静态工厂方法提供,都是匿名类。
- 同步
为任意一个集合增加线程安全。
- 不可修改
拦截所有修改集合的操作,并抛出UnsupportedOperationException。
- 类型检查
提供泛型集合,为指定的集合动态的增加类型安全,如果增加一种错误类型的元素,则抛出ClassCastException。
便利实现
Arrays.asList将数组转换为List。返回的List大小不允许改变,因为数组是不允许改变的。
Collections.nCopies 返回多个元素的N次拷贝。
Collections.singleton 返回只有一个元素的不变集合。
Collections的 emptySet, emptyList, 和 emptyMap方法,返回相应的集合,没有元素。
自定义Collection实现
为什么要自定义Collection?
1、持久化。所有集合实现都是存在于内存中,若程序重新启动数据就消失了。因此,可以将数据持久化到数据库,供多个程序使用。
2、高性能、特殊实现。
3、高性能、通用实现。
4、增强功能。
如何自定义Collection?
可以继承抽象类:
AbstractCollection、AbstractSet、AbstractList、AbstractSequentialList、AbstractQueue、AbstractMap