jdk-HashMap浅显探索

本文探索最常用到的方法的基本实现,其中关于红黑树的各种操作,这里不涉及。

先说下,HashMap底层是数组+链表/红黑树,即Node[]数组,Node是一个key-value的封装类,还有指向下一Node的指针。当HashMap中的元素数量超过capacity * loadFactor之后,进行resize,resize对于空数组,进行初始化分配,否则就进行2倍扩容和rehash。get时,直接拿table[key.hash & (n-1)]的值,若不是单Node,则通过链表/红黑树去找。put时,也是先看table[key.hash & (n-1)]是否为空,若不为空,则通过链表或红黑树插入,链表插入还需要考虑到>8转红黑树,以及插入完看是否需要resize。remove和put类似,只不过是个相反过程。

几个关键数值

Node类,实现了Map.Entry接口,把 <K, V>封装起来,构成Node链表。

暴露出去的公共方法

final方法:


注意到,HashMap的实现中,包括Node[] table本身,entrySet还有很多字段,都被声明为transient,这里有一篇可能有用的解答,也就是出于两个原因:

  1. 不同JVM有不同的hash实现,为了防止跨JVM的时候同一个字符串分布在不同位置,要阻止其序列化和反序列化。
  2. 效率。因为HashMap本质是存储key-value,那么其他的一切空间都只是辅助。