1. 初始容量
Collection
Set:
- HashSet
- TreeSet
- LinkedListSet
List:
- ArrayList
- 数组的默认大小为 10
- LinkedList
Queue
- PriorityQueue
Map
- TreeMap
- HashTable
- 默认为11
- 负载因子:0.75
- HashMap
- 不指明大小时,默认为16
- 负载因子默认为0.75
- 若给定初始容量initialCapacity,则返回的容量>=给定参数initialCapacity最小的2的幂次方的数值。
- LinkedHashMap
2. 扩容
Collection
Set:
- HashSet
- TreeSet
- LinkedListSet
List:
- ArrayList
- 新容量的大小为 oldCapacity + (oldCapacity>> 1) ,也就是旧容量的 1.5 倍。
- 需要调用 Arrays.copyOf() 把原数组整个复制到新数组中
- 最好在创建 ArrayList 对象时就指定大概的容量大小,减少扩容操作的次数。
- Vector
- 扩容请求其大小的 2 倍空间
- LinkedList
Queue
- PriorityQueue
Map
- TreeMap
- HashTable
- 扩展到2的倍数
- HashMap
- 扩展为oldCapacity*2+1
- 先扩展,再把旧数组里面的元素一个一个添加到新的里面
- 扩容机制包含了两部分:
- HahMap中table数组的容量的扩充;
- 成员属性threshold(即扩容的临界值)的更改。
- LinkedHashMap
3. 线程安全
Collection
Set:
- HashSet
- TreeSet
- LinkedListSet
List:
- ArrayList
- 不安全
- Vector
- 使用了synchronized 进行同步
- LinkedList
Queue
- PriorityQueue
Map
- TreeMap
- HashTable
- 安全
- 大多数方法都是加了synchronized关键字
- 安全
- HashMap
- 不安全
- Key与Value都允许为空
- get()和put()均无synchronized关键字修饰
- LinkedHashMap
4. 添加
Collection
Set:
- HashSet
- TreeSet
- LinkedListSet
List:
- ArrayList
- 添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,
- LinkedList
Queue
- PriorityQueue
Map
- TreeMap
- HashTable:
- 关于value,明显有if判断,不能为null。
- 如果key为null,则也直接在计算hashCode的时候就会报空指针异常。
- HashMap
- 允许null值和null键。
- 根据传入的key计算hash值,得到插入的数组索引i;
- 使用链表或者红黑树来解决冲突
- 如果tab[i]==null,则此下标处无元素存在,可直接添加元素,否则出现冲突。
- 如果出现冲突,则扫描链表或者红黑树。
- 在此过程中,可以使用equals()方法来确定是否存在该元素;
- 如果存在,则直接更新;
- 否则,采用链表或红黑树的方式将元素添加在tab[i]对应的链表或红黑树中。
- LinkedHashMap
5. 解决冲突的方式
Collection
Set:
- HashSet
- TreeSet
- LinkedListSet
List:
- ArrayList
- LinkedList
Queue
- PriorityQueue
Map
- TreeMap
- HashTable
- 只有链表
- HashMap
- 链表/红黑树
- 冲突数量<8,以链表方式解决冲突
- 冲突数量>=8,将冲突的Entry转换为红黑树进行存储
- 又当冲突数量<6时,有转换为链表进行存储
- 链表/红黑树
- LinkedHashMap