9、JDK1.8HashMap源码分析系列文章(replace、replaceAll)

【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 function)
/** * 根据指定函数,将map中的所有数据根据函数计算新的值,然后赋给对应的节点 * * @param function 指定函数 * @return void * @Author muyi * @Date 17:13 2020/8/4 */ @Override public void replaceAll(BiFunction 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}


    推荐阅读