hash方法源码参考

JDK 1.8
    static final int hash(Object key) {
      int h;
      // key.hashCode():返回散列值也就是hashcode
      // ^:按位异或
      // >>>:无符号右移,忽略符号位,空位都以0补齐
      return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
      //h >>> 16表示将整数h(32位)无符号右移16位,高位补0
      //直接使用hashcode,若多个键的哈希值仅高位不同,低位相同,会导致它们被分配到同一数组槽位
      //通过该操作,哈希值的低16位综合了高16位的信息,使得(n-1) & hash的结果更均匀分布,降低碰撞概率
  }



JDK 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);
}

拉链法:

即,将链表和数组结合,创建一个链表数组,数组中的每一格就是一个链表,遇到哈希冲突,则将冲突的值加到链表中

JDK 1.8以后,变化较大

实现原理

一、从JDK 1.7 和 JDK 1.8 版本区别回答

二、HashMap的put(key,val)和get(key)过程

HashMap一般用什么做Key,为什么

HashMap的扩容机制 / HashMap的大小为什么是2的n次方大小呢

扩容机制

hashMap默认的负载因子是0.75,即如果hashmap中的元素个数超过了总容量75%,则会触发扩容。扩容分为两个步骤:

为什么是2的n次方大小

浅看是适应扩容机制,但扩容机制又是适应: