关键代码
取hash
自身hashCode 按位异或 hashCode无符号右移16位
当数组的长度很短时,只有低位数的hashcode值能参与运算。而让高16位参与运算可以更好的均匀散列,减少碰撞,进一步降低hash冲突的几率。并且使得高16位和低16位的信息都被保留了。
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
元素定位
tab[i = (n - 1) & hash]
重现计算过程
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("在初始容量为16的HashMap中,字符串‘sun’的下标计算过程\n" +
"根据jdk1.8源码,元素hashCode计算方法: hashCode = (h = key.hashCode()) ^ (h >>> 16)\n" +
"元素落在数组的下标 tab[i = (n - 1) & hash])" +
"key.hashCode()=" + "sun".hashCode() + "\n" +
"二进制为:" + Integer.toBinaryString("sun".hashCode()) + "\n" +
"无符号右移16后 " + Integer.toBinaryString(("sun".hashCode()) >>> 16) + "\n" +
"hashCode 按位异或 无符号右移16的结果 " + Integer.toBinaryString(("sun".hashCode() ^ ("sun".hashCode()) >>> 16)) + "\n" +
"与(n-1) 按位 & 后 " + Integer.toBinaryString((15 & ("sun".hashCode() ^ ("sun".hashCode()) >>> 16))) + "\n" +
"转成10进制 " + (15 & ("sun".hashCode() ^ ("sun".hashCode()) >>> 16))
);
System.out.println(builder);
}