Search code examples
javadictionarysonarqube

Sonar use computeIfAbsent


I have this method:

private static void method(Integer key, final Map<Integer, Integer> aMap) {
  var value = aMap.get(key);
  if(value == null) {
    value = 0;
  }
  aMap.put(key, value + 1);
}

and Sonar analysis is telling me I should use Map#computIfAbsent, but I don't really know how to ensure the same result, since computeIfAbsent will update the map with 0, something which is not done as it is right now


Solution

  • You appear to want to put 1 in the map if no value exists, otherwise add 1 to the current value. I agree that using computeIfAbsent is not the best substitute for your current code. However, your use-case sounds like it would be perfectly solved by Map#merge(K,V,BiFunction):

    If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null.

    For example:

    static void method(Integer key, Map<Integer, Integer> map) {
        map.merge(key, 1, Math::addExact);
    }
    

    I used Math::addExact to prevent silent overflows. Whether you decide to keep that or use something like Integer::sum is up to you.


    Also, a benefit of merge is that it's thread-safe for ConcurrentMap implementations, if that matters here.