目录
2、higher / lower /ceiling / floor
4、pollFirstEntry / pollLastEntry
5、keySet / descendingKeySet / Iter
6、tailMap / headMap / subMap /SubMap
本篇博客继续上一篇《Java8 ConcurrentSkipListMap与ConcurrentSkipListSet (一) 源码解析》讲解ConcurrentNavigableMap相关方法的实现细节。
1、compute / merge
compute一共有三个方法,compute、computeIfAbsent和computeIfPresent,这四个方法的实现类似,都是先找到目标key,然后用remappingFunction计算结果,方法含义跟ConcurrentHashMap中一样的,不再赘述。
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (key == null || remappingFunction == null)
throw new NullPointerException();
for (;;) {
Node<K,V> n; Object v; V r;
if ((n = findNode(key)) == null) { //没有找到目标节点
if ((r = remappingFunction.apply(key, null)) == null) //计算返回null,跳出循环返回null
break;
if (doPut(key, r, true) == null) //r不为null,插入新节点,doPut返回值不是null,则重新for循环,进入下面的else if分支
return r;
}
else if ((v = n.value) != null) { //找到目标节点,如果value为null,下一次循环findNode会将该节点删除
@SuppressWarnings("unchecked") V vv = (V) v;
if ((r = remappingFunction.apply(key, vv)) != null) { //r不为null,修改value
if (n.casValue(vv, r)) //cas失败,则再次for循环
return r;
}
else if (doRemove(key, vv) != null) //r为null,删除节点
break;
}
}
return null;
}
public V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
if (key == null || mappingFunction == null)
throw new NullPointerException();
V v, p, r;
if ((v = doGet(key)) == null && //目标key不存在
(r = mappingFunction.apply(key)) != null) //计算结果非空
v = (p = doPut(key, r, true)) == null ? r : p;
return v;
}
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (key == null || remappingFunction == null)
throw new NullPointerException();
Node<K,V> n; Object v;
while ((n = findNode(key)) != null) { //目标key 存在且value非空
if ((v = n.value) != null) {
@SuppressWarnings("unchecked") V vv = (V) v;
V r = remappingFunction.apply(key, vv);
if (r != null) { //r不为null,修改value
if (n.casValue(vv, r))
return r;
}
else if (doRemove(key, vv) != null) //r为null,删除节点
break;
}
}
return null;
}
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (key == null || value == null || remappingFunction == null)
throw new NullPointerException();
for (;;) {
Node<K,V> n; Object v; V r;
if ((n = findNode(key)) == null) { //没有匹配的key,插入新节点
if (doPut(key, value, true) == null)
return value;
}
else if ((v = n.value) != null) { //找到目标key
@SuppressWarnings("unchecked") V vv = (V) v;
if ((r = remappingFunction.apply(vv, value)) != null) { //r不为null,修改value
if (n.casValue(vv, r))
return r;
}
else if (doRemove(key, vv) != null) //r为null,删除节点
return null;
}
}
}
2、higher / lower /ceiling / floor
这四个,每个都有两个方法,如ceilingKey和ceilingEntry,前者返回Key,后者返回一个Map.Entry键值对,总共8个方法;其中higher和lower相对,lower表示获取小于key的最大节点,higher表示获取大于key的最小节点;ceiling 与 floor相对,floor表示获取小于或者等于key的最大节点,ceiling 表示获取大于或者等于key的最小节点,其实现如下:
public Map.Entry<K,V> lowerEntry(K key) {
//找到小于key的最大节点
return getNear(key, LT);
}
public K lowerKey(K key) {
Node<K,V> n = findNear(key, LT, comparator);
return (n == null) ? null : n.key;
}
public Map.Entry<K,V> higherEntry(K key) {
//找到大于key的最小节点
return getNear(key, GT);
}
public K higherKey(K key) {
Node<K,V> n = findNear(key, GT, comparator);
return (n == null) ? null : n.key;
}
public Map.Entry<K,V> floorEntry(K key) {
//找到小于或者等于key的最大节点
return getNear(key, LT|EQ);
}
public K floorKey(K key) {
Node<K,V> n = findNear(key, LT|EQ, comparator);
return (n == null) ? null : n.key;
}
public Map.Entry<K,V> ceilingEntry(K key) {
//找到大于或者等于key的最小节点
return getNear(key, GT|EQ);
}
public K ceilingKey(K key) {
Node<K,V> n = findNear(key, GT|EQ, comparator);
return (n == null) ? null : n.key;
}
//rel是一个常量
final Node<K,V> findNear(K key, int rel, Comparator<? super K> cmp) {
if (key == null)
throw new NullPointerException();
for (;;) {
//找到最底层中接近key且小于key的节点b,然后往后遍历
for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
Object v;
if (n == null) //遍历万彩城
return ((rel & LT) ==