HashMap

HashMap

1. 底层数据结构?

  JDK1.7之前为链表+数组,JDK1.8后为链表+数组+红黑树
    数组是为了存储数据,链表为了解决hash冲突,红黑树为了方便查询
    链表长度到达8后hashmap,只有当链表长度>8且数组长度>=64时链表才会转换为红黑树。

2. hash算法

hashmap的put和get
    1.先根据key的值计算hash值
      (key == null) ? 0 : (h = key.hashcode() ^ (h >>> 16)) 向右无符号移动16位
    2. 根据hash值计算数组下标
      (length - 1) & hash
 目的是让数组下标更加分散

3. HashMap扩容机制

HashMap上的元素个数达到临界值(容量 * 负载因子)后会触发扩容,会重新rehash所有元素后放入扩容容器(新建的原数组两倍大)中

4. 为什么负载因子为0.75呢

   提供了一个良好的时间与空间成本的权衡(泊松分布)
 较大时会在扩容前发生更多的hash冲突,较小时会占用较多空间

5. JDK1.7 与 JDK1.8的改变

1. 数据结构
     增加了红黑树
2. 链表的插入方式由头插法改为尾插法
     JDK1.7之前头插法会使链表反转,多线程条件下会形成环
3. 扩容rehash
     JDK1.7之前扩容需要重新计算hash找位置,JDK1.8后不需要重新计算,新的位置不变或移动2的幂
4. 扩容时机
     JDK1.7前先判断是否需要扩容,再插入

6. HashMap HashTable

    两者都基于哈希表实现
  区别:
  1. 继承的类不同,但都实现了map接口
      hashmap继承abstractMap类,hashtable实现了
  2. hashmap线程不安全,hashtable安全
  3. HashTable不可以有Null值,而HashMap可以有

7. HashSet

底层为hashmap,hashset相当于其中的key
不能有重复数字,无序

8. ConcurrentHashMap

是安全的
JDK1.7前 是双数组结构 Segment + HashEntry
   Segment extends ReentranLock 为可重入锁
   HashEntry 被voliate 修饰,具有可见性
   
   put方法先由key选择出segment ,放入后加锁在放入HashEntry中
        
   
   
   
   
   
JDK1.8前 
   数组 + 链表 + 红黑树
   锁结构变为了 CAS + synchronized
   

锁变化的原因 
 1.ynchronized进行了优化,有多种锁状态,无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁
 2.减小内存消耗

9. linkedHashMap TreeMap

两者均为有序的map
 linkedhashMap 底层为hashMap的数据结构和双向链表
 treeMap 底层数据结构为红黑树,排序是根据比较器进行排序,无比较器则根据key的自然排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值