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);
如果键原先不存在,将把word与1关联,否则使用Integer.sum函数组合原值和1(也就是将原值与1求和)。
merge方法在写算法题以及工作中都是很常用的,应该吃透。
下面贴一下Map中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;
}
这里的源码还是很简单的,基本不用解释了。
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 ' ';
}
}

本文详细介绍了Java中Map接口新增的merge方法,包括其引入背景、工作原理及源码解析,并通过实例展示了如何利用该方法简化映射更新操作。同时,文章还提供了一个算法题示例,演示了merge方法的实际应用。
415

被折叠的 条评论
为什么被折叠?



