在填充HashMap时规避null检查

时间:2018-12-22 12:32:34

标签: java hashmap

在插入哈希表时,是否总是需要检查是否存在与要插入的键相对应的空值?

例如,如果我想使用散列图来跟踪字符在单词中出现的次数,我是否总是必须这样做:

if(hashMap.containsKey(ch)){
    hashMap.replace(ch, 1+hashMap.get(ch));    
}
else{
    hashMap.put(ch, 1);    
}

或者有可以为我处理此事的功能吗?

3 个答案:

答案 0 :(得分:17)

使用merge

 hashMap.merge(ch, 1, Math::addExact);

或使用方法参考:

ch
  • 如果指定的键(在这种情况下为1)尚未与某个值关联或与null关联,请将其与给定的非null值(在这种情况下为(left, right) -> left + right)关联。
  • 如果指定的键与非null值关联,则它将用给定的重映射函数Map的结果替换关联的值。

答案 1 :(得分:12)

您不必。 merge有一个hashMap.merge(ch, 1, (oldVal, newVal) -> oldVal + newVal); 方法,可用于更新值:

hashMap

这是什么:

  • 如果ch还没有ch键,则添加一个新条目,其中以1作为键,hashMap作为值
  • 如果ch已经具有一个以(oldVal, newVal) -> oldVal + newVal作为键的条目,那么将调用最后一个函数来计算更新值。在这种情况下,Map.compute只需将旧值添加到新值。

Andy's comment中所述,您也可以使用int newValue = hashMap.compute(ch, (key, existingVal) -> (existingVal == null) ? 1 : existingVal + 1);

>df1
V1  V2           V3           V4           V5
 a  abc|ccc|ggg  ttt|ccc|shg  yyy|lmn|trs  abc|ggt|hgy
 b  atc|cjc|ggg  ttt|ccc|shg  abc|lmn|trs  abc|opq|sss
 c  auc|chc|ggg  abc|ccc|shg  gtc|lmn|trs  hyt|lki|ddd
 d  aoc|cfc|ggg  ttt|ccc|shg  yyy|lmn|trs  rmn|wde|tre

答案 2 :(得分:1)

只需清楚一点,您不必区分键是否已存在于地图中。换句话说,可以在示例中使用replace,而不是在示例中使用put

当然,您确实需要处理是否具有需要包含在更新值中的先前值。正如其他人指出的那样,您可以使用mergecompute方法。

但是,如果您有理由更愿意坚持使用put,则这里有一些有关如何构造代码的想法。

在您的原始代码中,

if(hashMap.containsKey(ch)){
    hashMap.replace(ch, 1+hashMap.get(ch));    
}
else{
    hashMap.put(ch, 1);    
}

您调用containsKeyget,它们实际上都进行查找。为什么要两次查询?

Integer count = hashMap.get(ch);
if(count != null){
    hashMap.replace(ch, 1+count);    
}
else{
    hashMap.put(ch, 1);    
}

除了在一种情况下使用replace,在另一种情况下使用put,您也可以很容易地在两种情况下使用put。您可以结合两种情况:

Integer count = hashMap.get(ch);
if (count == null) {
    count = 0;
}
hashMap.put(ch, count + 1); 

我发现这种模式非常有用,而且它的作用很大(至少在我正在研究的应用程序中)。这是我对此的思考方式:

// Get the current value.
Integer count = hashMap.get(ch);
if (count == null) {
    // Business logic for initial value.
    count = 0;
}

// Compute the new value (might be a bunch of business logic).
count++;

// Put the new value back.
hashMap.put(ch, count);