1. remove
- 移除 key 元素对应的节点
/* 两个重载函数,区别在于是否指定元素的value值,底层都是调用 replaceNode */
public V remove(Object key) {
return replaceNode(key, null, null);
}
public boolean remove(Object key, Object value) {
if(key == null)
throw new NullPointerException();
return value != null && replaceNode(key, null, value) != null;
}
/* value: 替换的值,为null即删除, cv:指定key的旧值,不指定为null,指定需新旧值相等才删除 */
final V replaceNode(Object key, V value, Object cv) {
int hash = spread(key.hashCode()); // 获取 hash 值
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
/* tab没有元素,直接退出 */
if (tab == null || (n = tab.length) == 0 ||
(f = tabAt(tab, i = (n - 1) & hash)) == null)
break;
/* 正在扩容,帮助扩容获取新数组 */
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
boolean validated = false;
synchronized (f) {
/* 判断当前桶位首节点有没有被更改 */
if (tabAt(tab, i) == f) {
/* 链表节点 */
if (fh >= 0) {
validated = true;
for (Node<K,V> e = f, pred = null;;) {
K ek;
/* 找到节点 */
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
V ev = e.val;
/* 不指定旧值 || 新旧值相等,进行替换 or 删除 */
if (cv == null || cv == ev ||
(ev != null && cv.equals(ev))) {
oldVal = ev;
/* 替换和删除用的同一方法,使用 value进行区分 */
if (value != null)
e.val = value;
else