Java中merge方法在更新map中不存在的key对应的value时的妙用

merge方法引入

处理映射时的一个难点就是更新映射项。正常情况下,可以很容易的得到一个键关联的原值,完成更新,再放回更新后的值。不过必须考虑一个特殊情况,即键第一次出现。比如,我们需要使用一个映射统计一个单词在文件中出现的频度。看到一个单词(word)时,我们将计数器增1,学过C++的朋友肯定觉得太简单了,直接counts[word]++即可,因为counts中没有为word的键时,会自动添加该键。但Java中就没有那么方便了,Java中的做法如下所示:

counts.put(word,counts.get(word)+1);

这是可以的,不过有一种情况除外:就是word是第一次出现时。在该情况下,get会返回null,因此会出现一个NullPointerException异常。

避免该情况一个简单的做法是使用getOrDefault方法:

counts.put(word,counts.getOrDefault(word,0) + 1);

当然也可以使用putIfAbsent方法。

//如果传入的key已经有对应的value存在,返回存在的value,若不存在,则添加key和value,返回null
counts.putIfAbsent(word,0);
counts.put(word,counts.get(word) + 1);

但是还有更好的做法,merge方法可以简化这个常见的操作。

merge方法介绍

counts.merge(word,1,Integer::sum);

如果键原先不存在,将把word1关联,否则使用Integer.sum函数组合原值和1(也就是将原值与1求和)。

merge方法在写算法题以及工作中都是很常用的,应该吃透。

下面贴一下Mapmerge方法的源码:

    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;
    }

这里的源码还是很简单的,基本不用解释了。

merge方法使用举例

剑指 Offer 50. 第一个只出现一次的字符

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格s 只包含小写字母。

示例:

s = “abaccdeff”
返回 “b”


s = “”
返回 " "

限制:

  • 0 <= s 的长度 <= 50000
解题思路

直接遍历一遍字符串,用Map保存每个字符出现了多少次,再次遍历字符串,找到第一个只出现一次的字符即可。

Java代码
class Solution {
    public char firstUniqChar(String s) {
        //从头至尾遍历每个字符,用一个Map存好,key为字符,value为出现的次数
        if(s == null || s.length() == 0) return ' ';
        Map<Character,Integer> map = new HashMap<>();
        for(int i = 0;i < s.length();i++){
            map.merge(s.charAt(i),1,Integer::sum);
        }
        for(int i = 0;i < s.length();i++){
            if(map.get(s.charAt(i)) == 1){
                return s.charAt(i);
            }
        }
        return ' ';
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值