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 key      key
         * @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 = newValue;
                // ConcurrentHashMap使用的方法
                afterNodeAccess(e);
                return true;

            }
            return false;
        }

2、replace(K key, V value)

        /**
         * 与上面的方法唯一的区别是,只要存在key,不对旧值进行判断,直接将key对应的值修改为新值
         *
         * @param key   key
         * @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 = 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 = 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}

 

你可能感兴趣的:(HashMap源码分析)