getNode()方法: alt

解释:方法的参数需要一个hash值,以及一个key。方法的返回值是一个Node节点。定义了节点数组tab,头节点first.下一个节点e,长度n,以及键k。如果tab不为空,tab的长度n大于0,以及头节点不为空才会去找这个元素,否则直接返回null。当满足条件后,首先会判断头节点的哈希是否等于传入的hash值,传入的k等于头节点的k,接着头节点的k是否equals(k)。如果满足,则返回头节点。如果头节点不是要查找的节点,会让e=first.next,如果节点e不为空,接着会判断节点e是否是树节点,如果是则进行类型转换,转换后使用gettreeNode方法查找节点。如果不是树节点,则进行循环(循环的条件是e节点的下一个节点不为null),分别判断e节点的hash是否等于hash,e节点的k是否等于k,e节点的k是否equals(k)如果都等于,则返回e节点。

比较容易考的点: 1.hashMap的key能否为null?是可以为null,源码中表明当其为null时,hash值为0。

2.一个类如果重写equals,必须重写hashcode重写?

原因在于:hashMap是我们常用的集合类, 原因在于hashMap在使用getNode时,会先比较hash,接着比较equals。如果不重写,比如有两个字符串相同的那么他们的hash不同,但是equals却相同,就会让一个集合中存在两个一样的值。这显然不被允许。

3.扩容的时机:1.初始化时候扩容2.当节点的个数大于阈值时扩容3.在树化之前优先扩容。

4.树化的条件:链表的长度大于8,数组的长度小于64。

5为什么阈值选择8?原因在于泊松分布,往位置8插入的概率极低。

我们可以在hashMap源码中的put方法中的树化方法位置打上断点,大量的使用put方法在hashMap中添加数据,可以发现很难触发树化的方法,也就是说hashMap中树化的发生是比较少见的。