JDK1.7的实现中:
· 1. HashMap 和 HashSet 的默认大小是16。
· 2. Hashtable 的默认大小是11。
· 3. ArrayList 和 Vector 的默认大小是10。
· 4. ArrayDeque 的默认大小是8。
· 5. PriorityQueue 的默认大小是11。
问题:
· 1. HashMap 的默认大小为16,有什么特别的理由吗?
· HashMap 的容量大小需要保证为 2^n。
· HashMap 定位桶时是对桶容量( HashMap 容量)取余,(无论因果),该取余函数是用 h & (length- 1) 实现。
· 2. HashTable 的默认大小为11,有什么特别的理由吗?
· HashTable 的容量增加逻辑是乘2+1,保证奇数。
· 在应用数据随机分布时,容量越大越好。
· 在应用数据分布在等差数据集合(如偶数)上时,如果公差与桶容量有公约数n,则至少有(n-1)/n数量的桶是利用不到的。
· 实际上 HashMap 也会有此问题,并且不能指定桶容量。所以 HashMap 会在取模哈希前先做一次哈希,
· h ^= (h >>> 20) ^ (h >>> 12);
· h ^ (h >>> 7) ^ (h >>> 4);
· 3. ArrayList 默认大小为10,有什么特别的理由吗?
· ArrayList 的容量增长逻辑是乘 1.5 + 1,逻辑比较随意,看不出有什么特别含义。
· 4. ArrayDeque 默认大小为8,注释明确说明容量需要取 2^n。但是 ArrayDeque 内部存储结构是数组(没有哈希操作),并没有与问题1类似的需求。
· ArrayDeque 的容量大小需要保证为 2^n。
· ArrayDeque 使用 (tail - head)& (elements.length - 1) 计算 size()
· 5. PriorityQueue 默认大小为11,内部存储结构是数组(最小堆),却没有使用 2^n 而是11。
· PriorityQueue 的容量增长逻辑是 乘 2 或 1.5,逻辑比较随意,看不出有什么特别含义。