java工程师我爱编程技术干货

HashMap的存取原理你知道多少

2018-05-28  本文已影响42人  帅地

作者:小秋        公众号:苦逼的码农

在java的容器集合中,hashmap的使用频率可以说是相当高的。不过对于hashmap的存(put())以及取(get())的原理可能很多人还不大清楚,今天,我就给大家介绍下它是如何存如何取的

下面以回答问题的形式来讲解

假如有面试官问你,hashmap是如何存数据,你会怎么回答?

  1. 我想每个人都知道hashmap是以键值对的方式来存数据的,有些人可能会这么回答:当我们执行put(key, value)函数的时候,以key作为键,value作为值来存,并且如果key相同的话,则新的value会覆盖掉旧的value


这时面试官可能会问你,如果两个key对象的hashcode相同怎么办?

  1. 对于不熟悉hashcode()和equals()这两个方法的人来说,他可能会直接说,因为hashcode相同,那么两个对象是同一个对象,进而新的value覆盖掉旧的value。如果你这样回答,后果你懂 。(当然可能面试会提醒你或直接问你别的问题了)。
  2. 这个时候跑出来个第三者,自豪着补充了一句:根据hashcode找到对应的bucket之后,还会在对应的链表逐一检查这个链表里有没存在相同的key对象,这个时候是通过equals这个方法来对比的。如果有,者用新的value取代旧的value。如果没有,则向楼上说的,在链表的尾部加上这个新的Entry对象。

  1. 当我们调用get(key)的时候,会调用key的hashcode方法获得hashcode.
  2. 根据hashcode获取相应的bucket。
  3. 由于一个bucket对应的链表中可能存有多个Entry,这个时候会调用key的equals方法来找到对应的Entry
  4. 最后把值返回(这句好像是废话….但我还是想说下)。

继续涨知识……


大家都知道,当Map在扩容新的数组并且移动数据的时候,都是比较消耗时间和内存的,如果我们事先能预测到我们到存的数据的大致大小的话,我们就可以新创建hashmap的时候指定大小,这样,可以大小减少扩容带来的消耗。

  1. 负载因子越大,数组要被填满时,元素就会越多,元素越多,冲突的几率就会越大,一个链表存的元素也会越多,查询的时候就会越慢。但是,此时空间的利用率更高了——空间换时间
  2. 负载因此越小,数组要被填满时,元素就会越少,冲突也会也少,一个链表的元素也会越少,查询的时候也就越快。但是,空间的利用率低了——-时间换空间。

上一篇下一篇

猜你喜欢

热点阅读