JAVA 底层 (一) HashMap

目录

一、原理

二、扩容

三、Hashcode

四、遍历方式

五、总结汇总


HashMap 是在JAVA比较常用的一个对象,其底层实现原理 数组+链表的结构实现的(PS:jdk 8 后 变成数组+<链表/红黑树(链表元素个数大于8切换成红黑树)>)

一、原理

以下简单图为例,当一个HashMap创建时 ,会创建一个空数组 。

当使用 put()方法时,也就是添加key-value 元素进去,底层是将 key通过hashCode()方法 得到一个整数,作为数组的下标存放 元素,但当key的hashCode相同(即hash碰撞)就会在 相同的下标位置,在上一个的元素后添加,形成一个链表结构,且上一个存在元素是带有 下一个元素的指向。

当使用get()方法获取元素时,底层是拿到key的hashcode,然后通过code定位下标,再通过equla()方法判断key是否相等来获取 元素的值。

二、扩容

在使用 new HashMap< , >()时,默认的扩容系数是0.75,初始大小是16,也就是说当存在的元素数量超过12时,就会自动rehash。进行2*16(2n)一个扩容。扩容操作是非常消耗性能,会对下标重新进行分配。

三、Hashcode

HashMap的HashCode是一个散列的一个集合,对象能在里面找到一个属于自己的code,具体是通过java Hash算法 通过位运算得出。不同的对象有可能会得出相同的hashCode(碰撞)

四、遍历方式

HashMap<String,String> map=new HashMap<>();
Iterator it=map.entrySet().iterator();
while (it.hasNext()){
            Map.Entry entry= (Map.Entry) it.next();
            Object key=entry.getKey();
            Object value=entry.getValue();
        }

五、JDK1.8

HashMap 在JDK8 后 put()换成了尾部插入法,在当链表长度大于8时,链表会转换成红黑树,查询复杂度从0(n)变成0(Log n)

六、总结汇总

Hashtable的实现基本和HashMap一致,区别在hashcode生成的方式与取模,以及加了 synchronized 进行一个线程安全,所以性能略低

PS:线程不安全的原因,hashMap在数据 扩容的时候,会将链表的元素位置反转, 如果两个线程同时操作的,就会形成两个反转,形成循环锁死状态。

数组+链表结构初始大小扩容扩容系数hashCode线程key,value
HashMap162n0.75位运算不安全可以为空
HashTable112n+10.75取模安全不可为空

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值