上篇文章分析了keySet内部类,然后发现Values和EntrySet的原理是差不多的,下面就对一下比较不一样的方法进行分析
- EntrySet的contains()方法:
用于判断Map内是否包含某节点,返回boolean类型,
必须key和value都和Map中的某个节点K,V相同,才返回true
public final boolean contains(Object o) {
if (!(o instanceof Map.Entry)) // 判断参数是否为Map节点
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey(); // 获取节点key
Node<K,V> candidate = getNode(hash(key), key); // 遍历链表获取节点
return candidate != null && candidate.equals(e); // 节点不为null,并且和参数相等,返回true
} - getOrDefault()方法:
传入key和默认的value,如果Map中key节点的值为空,则返回defaultValue,否则返回key节点的value值
public V getOrDefault(Object key, V defaultValue) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
}putIfAbsent - putIfAbsent()方法:
方法重写于Map接口,当查找到的key节点的value值为null时,覆盖value值,否则不进行覆盖,
当value初始值不为null的时候,putIfAbsent()保证返回值始终是唯一的,并且是多线程安全的,
区别于put()方法,put()方法会覆盖旧值
public V putIfAbsent(K key, V value) {
return putVal(hash(key), key, value, true, true); // 第三个参数onlyIfAbsent用于控制是否覆盖旧值, put()方法的onlyIfAbsent为false
} - remove(Object key, Object value)方法:
删除Map中key和value都和参数相同的节点 - replace()方法:
指定的key已存在,并且value和oldvalue相等,就用新值(newValue)覆盖旧值,并返回true,
指定的key不存在,就返回false
public boolean replace(K key, V oldValue, V newValue) {
Node<K,V> e; V v;
if ((e = getNode(hash(key), key)) != null && // 查找key,并判断value是否等于oldValue,是则用newValue覆盖,并返回true,否则返回false
((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
e.value = newValue; // 覆盖旧值
afterNodeAccess(e);
return true;
}
return false;
}
指定的key已经存,就用新制覆盖旧值,在指定的key不存在时,方法返回null
public V replace(K key, V value) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) != null) { // 获取key节点,覆盖旧值并返回旧值,否则返回null
V oldValue = e.value;
e.value = value;
afterNodeAccess(e);
return oldValue;
}
return null;
}