JDK集合框架源码分析 - 简单概要
1.类继承体系
在集合框架的类继承体系中,最顶层有两个接口Collection、Map;
- Collection 表示一组纯数据
- Map 表示一组key-value对
Collection的类继承体系:
Map的类继承体系:
2.集合框架
2.1 ArrayList
可变数组的实现,高效随机访问RandomAccess ,但插入和删除元素时需要复制数组,开销较大;默认容量10,扩容为原来的1.5倍(oldCapacity + (oldCapacity >> 1));
fail-fast : modCount记录容器发生结构化修改的次数(ensureExplicitCapacity 方法中加1)
添加:add、add(index, E)、add(Collection)、add(index, Collection)
移除:remove、fastremove(System.arraycopy)、置null来GC、trimToSize调整数组大小
获取和修改:indexof、get、set(不会修改modCount)
迭代、SubList子列表、序列化
2.2 HashMap
哈希表实现(单向链表),数组中每一个元素都是一个链表,把数组中的每一格称为一个桶(bin或bucket);容量默认为16、装载因子0.75f、扩容x2;
哈希碰撞问题;
hash实现:在Java 1.8的实现中,是通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在bucket的n比较小的时候,也能保证考虑到高低bit都参与到hash的计算中,同时不会有太大的开销
链表转化成红黑树TREEIFY_THRESHOLD = 8,红黑树转化成链表UNTREEIFY_THRESHOLD = 6;
2.3 Vector 与 Stack
(不推荐,推荐使用 Deque 接口的实现,如 LinkedList 和 ArrayDeque)
Vector 可增长对象数组,线程安全;扩容加倍
Stack 基于Vector,LIFO
2.4 Deque 与 ArrayDeque
Collection -> Queue -> Deque 具体实现ArrayDeque ;
Deque 双端队列;
ArrayDeque可变数组实现,自动扩容,不支持null;默认容量16,必须为2^n;
2.5 LinkedList
双向链表实现,实现了Deque 接口;
2.6 LinkedHashMap
基于链表和哈希表实现,扩展HashMap 增加了双向链表的实现;
支持按插入序 (insertion-order) 或访问序 (access-order) 来访问其中的元素;访问顺序LRU;
支持为 null 的键和值;
双向链表将所有的 Entry 串在一起,支持按照插入顺序或访问顺序来遍历所有的 Entry;
2.7 枚举
类型安全和可读性,实现了 values() 和 valueOf() 这两个静态方法;
单例模式实现(最佳方案);
Enum(name,ordinal)
EnumSet 必须是来自同一个 enum,内部使用 bit 向量实现,这种实现方式更紧凑高效;
EnumMap 是一种特殊的 Map,要求其中的键 (key) 必须来自于同一个 enum。由于自身的实例数量有限,在内部可由数组实现,因此速度很快;
2.8 TreeMap
基于红黑树实现的 Key-Value 结构;SortedMap -> NavigableMap -> TreeMap;
非线程安全;
Key默认自然序,不支持null,也可实现 Comparable 接口,自定义比较器可以接受null;
2.9 Set
内部通常基于 Map实现,Map 中的 Key构成了 Set,而 Value 全部使用一个无意义的 Object ;
基于 HashMap 的 HashSet 是无序时的最佳通用实现,
基于 LinkedHashMap 的 LinkedHashSet 保留插入或访问的顺序,
基于 TreeMap 的 TreeSet 可以按照元素升序排列,要求元素实现 Comaprable 接口或自定义比较器以上都是非线程安全;
2.10 CopyOnWriteArraySet
线程安全,并发优化的ArrayList,通过 CopyOnWriteArrayList 实现;
CopyOnWriteArrayList,是一个线程安全的List接口的实现,它使用了ReentrantLock锁来保证在并发情况下提供高性能的并发读取;
3.注意点
1.基于结构化修改的次数来实现 fail-fast 机制,比较modCount 和 expectModCount;
源码分析:
http://blog.jrwang.me/tags/Source-Code-Analysis/