【9、JDK1.8HashMap源码分析系列文章(replace、replaceAll)】目录
1、replace(K key, V oldValue, V newValue)
2、replace(K key, V value)
3、replaceAll(BiFunction function)
1、replace(K key, V oldValue, V newValue)
/**
* map中指定key存在并且对应的值与指定的旧值相等的时候,才替换成功,否则替换失败
*
* @param keykey
* @param oldValue 旧值
* @param newValue 新值
* @return boolean
* @Author muyi
* @Date 17:03 2020/8/4
*/
@Override
public boolean replace(K key, V oldValue, V newValue) {
HashMap.Node e;
V v;
/**
* 以下两个条件与
* 1、e = getNode(hash(key), key)) != null:key对应的不为null的元素找到
* 2、((v = e.value) == oldValue || (v != null && v.equals(oldValue)))):
* 找到节点的值与地址相等,或者旧值不为null的时候,两者的值相等
* 两个条件同时满足的时候,才可以修改成功,否则修改失败
*/
if ((e = getNode(hash(key), key)) != null &&
((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
e.value = https://www.it610.com/article/newValue;
// ConcurrentHashMap使用的方法
afterNodeAccess(e);
return true;
}
return false;
}
2、replace(K key, V value)
/**
* 与上面的方法唯一的区别是,只要存在key,不对旧值进行判断,直接将key对应的值修改为新值
*
* @param keykey
* @param value 新值
* @return boolean
* @Author muyi
* @Date 17:03 2020/8/4
*/
@Override
public V replace(K key, V value) {
HashMap.Node e;
if ((e = getNode(hash(key), key)) != null) {
V oldValue = https://www.it610.com/article/e.value;
e.value = value;
afterNodeAccess(e);
return oldValue;
}
return null;
}
3、replaceAll(BiFunction super K, ? super V, ? extends V> function)
/**
* 根据指定函数,将map中的所有数据根据函数计算新的值,然后赋给对应的节点
*
* @param function 指定函数
* @return void
* @Author muyi
* @Date 17:13 2020/8/4
*/
@Override
public void replaceAll(BiFunction super K, ? super V, ? extends V> function) {
HashMap.Node[] tab;
if (function == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
// 保存修改值
int mc = modCount;
for (int i = 0;
i < tab.length;
++i) {
for (HashMap.Node e = tab[i];
e != null;
e = e.next) {
e.value = https://www.it610.com/article/function.apply(e.key, e.value);
}
}
// 在整个替换过程中,map的数据一旦被别的线程进行了添加、修改等操作,改变了modCount的值,抛并发修改异常
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
使用举例
HashMap hashMap = Maps.newHashMap();
for (int j = 1;
j <= 10;
j++) {
hashMap.put(j, j);
}
System.out.println(hashMap);
hashMap.replaceAll(new BiFunction() {
@Override
public Integer apply(Integer o, Integer o2) {
o2 = 2;
return (int)Math.pow(o,o2);
}
});
System.out.println(hashMap);
{1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10}
{1=1, 2=4, 3=9, 4=16, 5=25, 6=36, 7=49, 8=64, 9=81, 10=100}
推荐阅读
- 7、JDK1.8HashMap源码分析系列文章(putMapEntries、tableSizeFor、hash、capacity)
- 10、JDK1.8HashMap源码分析系列文章(remove、removeNode、removeTreeNode、balanceDeletion)