HashMap的底层实现及Jdk 1.7-1.8的变化

  • 异、或、与–位运算二进制运算
    • &两位同时为“1”,结果才为“1”,否则为0
      • 1+1=1
    • |参加运算的两个对象只要有一个为1,其值为1。
      • 1+a=1
    • ^参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
      • a+(!a)=1
      • a+a=0
  • hashmap
  1. hashmap的数据储存结构
    • Jdk 1.7由数组和链表结构组成
    • Jdk 1.8之后由数组,链表和红黑树组成,当链表长度大于8时就会转成红黑树结构
  2. HashMap的默认容量
    • 16
  3. HashMap的数组大小为什么初始空间是2的幂
    • 因为只有长度是2的n次方的数,进行减一操作得到的数的二进制结果的低位才能拿到全部是1的值,再进行按位与运算就能非常快速的拿到数组的下标,并且分布是均匀的
      static final int tableSizeFor(int cap) {
           int n = cap - 1;
           n |= n >>> 1;
           n |= n >>> 2;
           n |= n >>> 4;
           n |= n >>> 8;
           n |= n >>> 16;
           return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
       }
       例:14
       0000 1110
       n |= n >>> 1;      0000 1110  | 0000 0111    =  0000 1111
       n |= n >>> 2;      0000 1111  | 0000 0011    =  0000 1111
       ...
       n |= n >>> 16;     0000 1111  | 0000 0000    =  0000 1111
      
    • 在进行长度计算时,右移并或运算将低位全部补1,最后一步再+1就能得到2的幂
  4. HashMap扩容—resize
    • 当capacity(容量) * load(负载因子–0.75f) > threshold(预值)时进行扩容一倍
    • 1.7头插法
      • 将原来的数据迁移到新的hashmap中,并且要rehash
      • 数据迁移时哈希桶的链表的数据顺序进行调换
        • 当多线程同时进行数据的更改时,会产生循环链表,导致死锁
    • 1.8尾插法
      • 通过e.hash & oldCap来判断迁移后元素的新下标,并且新的链表的顺序和之前的顺序一致,从而避免了环形链表的出现
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值