jdk1.7 1.8 hash map 区别及一些细节
1 扩容
1.7
void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; if (rehash) { e.hash = null == e.key ? 0 : hash(e.key);重点 } int i = indexFor(e.hash, newCapacity);重点 e.next = newTable[i]; newTable[i] = e; e = next; } } }
1.8
do { next = e.next; if ((e.hash & oldCap) == 0) { 重点 if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null); if (loTail != null) { loTail.next = null; newTab[j] = loHead;重点 } if (hiTail != null) { hiTail.next = null; newTab[j + oldCap] = hiHead;重点 }
2 jdk8 引入红黑树
3 1.7 先扩容再插入,1.8先插入再决定是否扩容
4 1.7头插(
同一位置上新元素总会被放在链表的头部位置;这样先放在一个索引上的元素终会被放到Entry链的尾部
),1.8尾插
细节:为什么是8
1)treenodes的大小大约是常规节点的两倍——决定了不能直接用,有优势也有开销
2)红黑树平均查找长度是log(n),长度为8的时候,平均查找长度为3,如果继续使用链表,平均查找长度为8/2=4,这才有转换为树的必要
3)还有选择6和8,中间有个差值7可以有效防止链表和树频繁转换。
细节:为什么0.75
如果是0.5 , 那么每次达到容量的一半就进行扩容,默认容量是16, 达到8就扩容成32,达到16就扩容成64, 最终使用空间和未使用空间的差值会逐渐增加,空间利用率低下。 如果是1,那意味着每次空间使用完毕才扩容,在一定程度上会增加put时候的时间及hash冲突的可能,提高读写的成本
空间使用率和性能的折中
红黑树根据什么排序:
如果key没有实现Comparable接口
if (x instanceof Comparable) { Class<?> c; Type[] ts, as; Type t; ParameterizedType p; if ((c = x.getClass()) == String.class) // bypass checks return c; if ((ts = c.getGenericInterfaces()) != null) { for (int i = 0; i < ts.length; ++i) { if (((t = ts[i]) instanceof ParameterizedType) && ((p = (ParameterizedType)t).getRawType() == Comparable.class) && (as = p.getActualTypeArguments()) != null && as.length == 1 && as[0] == c) // type arg is c return c; } } } return null;
static int tieBreakOrder(Object a, Object b) { int d; if (a == null || b == null || (d = a.getClass().getName(). compareTo(b.getClass().getName())) == 0) d = (System.identityHashCode(a) <= System.identityHashCode(b) ? -1 : 1); return d; }
先根据类名,再根据identityHashCode
identityHashCode根据对象的内存地址来计算hashcode,不管对象是不是重写了hashcode
https://blog.csdn.net/weixin_41725090/article/details/82147576
https://blog.csdn.net/qq_36520235/article/details/82417949