Map 的 computeIfAbsent computeIfPresent compute merge 方法的运用

Map computeIfAbsent computeIfPresent compute merge 方法的运用

前言

本文介绍几个 Map 接口提供的小方法

computeIfAbsent

	default V computeIfAbsent(K key,
            Function<? super K, ? extends V> mappingFunction) {
        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = get(key)) == null) {
            V newValue;
            if ((newValue = mappingFunction.apply(key)) != null) {
                put(key, newValue);
                return newValue;
            }
        }

        return v;
    }

Function函数式接口,接受一个输入参数,返回一个结果。

该方法会在不存在指定 key 时,以函数的结果为 value 保存该 key

看一段示例 demo

	/**
     * 对出现的数字计数
     */
	@Test
    public void test1() {
        Integer[] is = {1, 1, 2, 2, 2, 3, 3, 4};
        Map<Integer, Integer> numMap = new HashMap();

        for (int i : is) {
            if (numMap.containsKey(i)) {
                numMap.put(i, numMap.get(i) + 1);
            } else {
                numMap.put(i, 1);
            }
        }

        numMap.forEach((k, v) -> System.out.println(k +":"+ v));

        System.out.println("by use computeIfAbsent");

        Map<Integer, Integer> numMap2 = new HashMap();
        for (int i : is) {
            numMap2.put(i,
                    numMap2.computeIfAbsent(i, k -> 0) + 1);
        }

        numMap2.forEach((k, v) -> System.out.println(k +":"+ v));
    }

可以看到,使用 computeIfAbsent 会让整个方法简单、清晰

computeIfPresent

	default V computeIfPresent(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        V oldValue;
        if ((oldValue = get(key)) != null) {
            V newValue = remappingFunction.apply(key, oldValue);
            if (newValue != null) {
                put(key, newValue);
                return newValue;
            } else {
                remove(key);
                return null;
            }
        } else {
            return null;
        }
    }

BiFunction,接受两个输入参数的方法,并且返回一个结果。

对于存在的 k,用不为 null 的函数结果值代替,否则移除 k。若 k 不存在,则什么也不干

demo

	/**
     * 只对出现的 1 计数
     */
    @Test
    public void test2() {
        Integer[] is = {1, 1, 2, 2, 2, 3, 3, 4};
        Map<Integer, Integer> numMap = new HashMap();
        numMap.put(1, 0);

        for (int i : is) {
            if (i == 1) {
                numMap.put(1, numMap.get(1) + 1);
            }
        }

        numMap.forEach((k, v) -> System.out.println(k +":"+ v));

        System.out.println("by use computeIfPresent");

        Map<Integer, Integer> numMap2 = new HashMap();
        numMap2.put(1, 0);

        for (int i : is) {
            numMap2.computeIfPresent(i,
                    (k, v) -> ++v);
        }

        numMap2.forEach((k, v) -> System.out.println(k +":"+ v));
    }

compute

	default V compute(K key,
            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        V oldValue = get(key);
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue == null) {
            if (oldValue != null || containsKey(key)) {
                remove(key);
                return null;
            } else {
                return null;
            }
        } else {
            put(key, newValue);
            return newValue;
        }
    }

computeIfPresent 差不多,就不说明了

merge

	default V merge(K key, V value,
            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if(newValue == null) {
            remove(key);
        } else {
            put(key, newValue);
        }
        return newValue;
    }

computeIfPresent 差不多,唯一的区别是入参多了个 v,指定 k 不存在时,以传入的 v 存储该 k

总结

Map 提供的这几个方法,在特定场景下可以大幅度优化我们的代码,让整个代码更加优雅轻便

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值