HashMap源码研究

研究HashMap的源码,主要是研究下面几个点:

get

put

table

entrySet

Entry


特别是put方法, Entry的数据结构。


jvm7和jvm8的源码是有差异的。


先说下思路。 想取的快,一定是存的时候根据了规则,能够快速定位。这个就像数据库的表建立索引一样。想查询的快,那么就要根据规则建立索引。

也就是想get快,那么就put的时候有规则,能够快速在table中进行定位,也就是快速拿到table数组的下标。


那么这个下标的数值就是根据key的值进行计算的。虚拟机每个版本的计算方式不一样。


jvm7是根据key的hash值与table的数组长度进行与操作,得到一个下标。 hash的算法就是一些位移及异或操作。

h^= (h >>> 20)

^ (h >>>

12);

       returnh ^ (h >>> 7) ^ (h>>> 4);


jvm8的hash计算公式又不一样:

return (key == null) ? 0 : (h =key.hashCode()) ^ (h >>> 16);

基本上也是位移及异或操作。


   那么get的时候,也是根据相同的hash算法,取得key对应的下标,然后就可以快速从table数组中获取到数据啦。


Entry因为是个内部类,HashMap又引用了Entry,所有我们的hashmap实例的entry是无限嵌套的。

   还有一个注意的,就是entry里面有个Entry的next属性。为什么会有这个属性呢? 大部分时候这个next是为null的。因为有时候key的hash值计算是一样的。

Map aaaa = new HashMap

Integer>();

      aaaa.put(3, 1);

      aaaa.put(18, 1);

比如用int类型的map很容易模拟出来。3和18的在map的hash值是一样的。这样在table数组里面的下标3的地方只有key为18的entry,那么key为3的entry呢,就是在key为18的entry的next中。 实际的table数组中的元素可能就会比真实的entry数量会少。

你可能感兴趣的:(HashMap源码研究)