Java HashMap

本文详细介绍了Java HashMap的数据结构,包括其key是HashSet集合,无序且不可重复的特点。HashMap底层基于Hash表,由key、value、hash和next组成。每个元素的链表中节点的hash值相同,用于定位数组下标。put方法根据key的hashCode计算位置,若已存在链表则遍历比较key。get方法同样依据hashCode找到下标并遍历链表。重点讨论了hashCode和equals重写的重要性,负载因子0.75的原因,以及扩容机制。
摘要由CSDN通过智能技术生成

HashMap

HashMap的key就是HashSet集合,无序、不可重复
HashMap底层是一个Hash表,属性有key,value,hash,next
数组中每个元素中的单向链表的每个节点的hash值是相同的,该hash值就是该单向链表所在的元素的 下标,hash值是通过调用key的hashCode()方法经过hash算法得到的.

HashMap的put(k,v)方法实现原理:

  • 1. 当调用put(k,v)时,会将传入的key和value封装到Node对象中

  • 2.再调用key的hashCode()方法得出hash值,通过hash算法计算出对于数组中的下标,如果下标中没有元素,那么直接将此Node对象添加到当前位置,如果下标中已经存在链表了,那将会用Node中的key和每一个节点中的key进行equals(),如何全部返回false,就将Node添加至链表的末尾,如果有一个返回true,那么将其value值覆盖(也就是hashMap中的key重复,value覆盖)

HashMap的get(k)方法实现原理:

  • 当调用get(k)方法时,先调用k的hashCode()方法,得出hash值,再通过hash算法的到数组对应的下标,如果当前下标没有元素,那麽直接返回null,否则用key对链表中的每一个节点的key进行equals(),如果为true,将会返回此key对应的value值!如果每一个节点都返回false,表示没有找到,返回null

重点:

  • 1. 在Hash表中,每一个下标对应的节点中的hash值是相同的,表示这些节点存在于同一张单向链表上,这也是为什么需要重写hashCode()方法,如果不重写,将会调用Object中的hashCode(),那样会导致每一个节点对象的hash值都不相同,每个Node都会被添加到数组对应下标的第一个元素中!

  • 2. 为了保证元素的不重复,所以需要重写equals()方法,因为HashMap中的key就是HashSet集合,所以存储在HashSet中的元素也需要重写HashCode()和equals()方法

  • 3. 如果重写的hashCode()都返回固定的值,那样会导致所有的Node的hash值相同,全部挂在一张链表上,此时的hash表就成了单向链表,反之,如果重写的hashCode()方法全都返回不同的值,那么每个Node的hash值都不同,就变成了一维数组,以上问题称之为:散列分布不均匀

  • 4. HashMap的默认初始化容量为16,默认加载因子是0.75,当数组容量达到75%时,进行扩容
    比如当前默认初始化容量为16,负载因子为0.75,16*0.75 = 12, 当数组容量达到12,进行扩容

  • 5. HashMap的初始化容量必须是2的倍数,这是为了散列分布均匀,和提高存取效率

关于HashMap的负载因子

  • 负载因子相当于是一个扩容机制的阈值,当容量超过这个阈值,就会引发扩容机制,默认是0.75,但是可以通过构造方法指定

  • 为什么要设置为0.75?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值