JDK1.8和1.7下的HashMap的区别
一 1.8之前哈希表主要由数组加上链表组成(拉链法解决冲突)。
1.8 之后由数组和链表或者红黑树组成,当满足以下两个条件的时候,链表会转换成红黑树。
- 链表的长度大于8
- 数组的长度大于64
二 hash()变了,变的更加简单,冲突更少了。
如下是1.8的方法
static final int hash(Object key) {
int h;
// key.hashCode():返回散列值也就是hashcode
// ^ :按位异或
// >>>:无符号右移,忽略符号位,空位都以0补齐
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
如下是1.7的方法
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
三 1.7版本插入链表采用的是头插法,在线程不安全的情况下可能会使得链表形成环;1.8版本插入链表采用的是尾插法。
四 当需要扩容的时候,1.7是插入前扩容,1.8是插入成功后扩容。
ConcurrentHashMap 1.7和1.8的区别
ConcurrentHashMap是线程安全的。
1.7下实现线程安全是通过Segment + HashEntry数组 + 链表实现的,默认16个segment;
1.8下抛弃了Segment,采用了Node数组 + 链表/红黑树实现。使用Synchronized锁 和 CAS来实现线程安全。
参考资料:
JavaGuide