HashMap JDK1.8原理

HashMap原理:

数组+链表/红黑树

变量:初始化大小16,最大容量2^30,负载因子0.75,链表转红黑树8,红黑树转链表6,最小转数容量32

为什么是数组?
效率更高 & 扩容2倍数,符合hashmap扩容原则,方便计算下标:(hashcode-1)&capacity
*ArrayList扩容倍数为1.5 capacity+capacity>1*
Node:
Key,value,hashcode,next
链表转红黑树8,红黑树转链表6 ?
给一个7作为缓冲,持续的转换性能不高
Hash函数:
h = key.hashcode() ^ (h>>16)  高16位+高16位异或低16
将大范围数变成小范围数
PUT
  1. 根据hash&(capacity-1)计算下标;
  2. 判断bucket中tab[下标]==null,如果为null,直接插入;
  3. 判断hash,key是否一样,一样则更新;
  4. 判断当前tab[下标]是否位treenode,是则以treenode的方式添加;
  5. 插入到链表中
  6. 判断是否需要转为Tree
  7. 扩容判断
GET
  1. 根据hash&(capacity-1)计算下标;
  2. 判断bucket中tab[下标]是否存在,不存在返回null;
  3. 判断hash,key是否一样,一样则返回;
  4. 判断next是否为null;
  5. 判断当前类型是否为tree,是则以tree的方式查找;
  6. 不是tree,则循环走3直到结束;
Resize
  1. 复制原来的Node到新的map, 之前低位的还是挪动到新Map的低位,之前高位的挪动到新Map的原位置=旧位置+旧长度
  2. 低位计算:(e.hash & oldCap) == 0
  3. LoHeader,Lotail,HiHeader,HiTail
并发问题/线程不安全:
  1. 多线程扩容,出现死循环问题;[++size][1.7头插入1.8尾插]
  2. 多线程PUT元素,丢失;
    解决方案: hashtable[加synchronized锁,效率太低] ConcurrentHashMap[分段hash]
Key可以为null,但是只有一个;Value可以存在多个null
一般用不变量:Integer,String作为Key
使用不变类作为key时:
- 需使用final修饰,不能继承,以免修改,
- 构造器初始化成员深copy, 
- 需要重写hashcode(), equals(),
- getter方法需要返回一个深copy,以免被修改/防止对象外泄
String的hashcode
h = 31 * h + val[i];
31*(31*(31*0+[0])+[1])+[2]……=[0]*31^(n-1)+[1]*31^(n-2)+……+[n-1]
31是一个不大不小的奇质数
HashMapJava中常用的数据结构之一,它基于哈希表实现。在JDK 1.8中,HashMap的底层实现主要包括数组和链表(或红黑树)两部分。 首先,HashMap内部维护了一个Entry数组,每个Entry对象包含了键值对的信息,包括键、值和指向下一个Entry的指针。数组的长度是固定的,但可以根据需要进行扩容。 当我们向HashMap中插入一个键值对时,首先会根据键的hashCode()方法计算出一个哈希值。然后,通过哈希值与数组长度取模的方式确定该键值对在数组中的位置。如果该位置上已经存在其他键值对,就会发生冲突。 解决冲突的方法是使用链表或红黑树。在JDK 1.8中,当链表长度超过一定阈值(默认为8)时,链表会换为红黑树,以提高查找效率。这样,在插入、删除和查找操作时,可以通过哈希值快速定位到对应的链表或红黑树,然后再在链表或红黑树中进行操作。 当我们需要查找一个键对应的值时,HashMap会根据键的哈希值找到对应的位置,然后遍历链表或红黑树来找到具体的键值对。 需要注意的是,HashMap并不保证元素的顺序,即插入和遍历的顺序不一定相同。如果需要有序的集合,可以考虑使用LinkedHashMap。 总结一下,JDK 1.8中HashMap的底层原理主要是通过数组和链表(或红黑树)来实现,通过哈希值快速定位到对应的位置,然后在链表或红黑树中进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值