顺便也说说如何判断是相等的key,然后用新的值替换旧的值?
**方法put,注意hash(key)这个方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
方法putVal,注意前2个参数,一个是key的hash值,一个是key
/**
* Implements Map.put and related methods
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent if true, don't change existing value
* @param evict if false, the table is in creation mode.
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)
HashMap的put方法步骤如下:
1、判断( table是否为null或者table的长度是否为0 )?
如果是,调用resize方法

2、判断( hash & table的长度-1 对应的数组位置是否有值 == null)?
如果没有值,new一个节点赋给它。

3、如果数组的位置上有值,继续如下步骤:
1)传入的key跟旧key比较,首先判断key的hash是否相等,并且key的( 引用相等 或者 值相等),就认为是相同的key,需要替换新值,返回旧值。

2)判断旧的节点是否树节点,
如果是,执行putTreeValue。

3)遍历到链表队尾,在链表上创建新节点,放在队尾。

4)判断是否需要扩容

总结:
主要考点:
-
如何判断传入的key和存在的key是相同的key,然后用新值替换旧值?
首先判断key的hash是否相等,因为相等的对象它们的hash一定相等,反之不成立;这样可以加快比较的效率、提高性能。
再判断 引用相等 或者 值相等 ,它们只要一个为true就认为对象相等。考官会问你,你可能答得不全。
-
考“JDK 8以前:新元素直接挂在老元素后面; 而在JDK 8之后,为了防止链表过长,导致降低查找效率,当链表长度大于8时,链表就会自动的转化为红黑树”
-
考什么时候扩容?