Puede que sea un poco tarde, pero aquí están mis dos centavos.
Si está utilizando Java 8, puede utilizar el método computeIfPresent . Si el valor para la clave especificada está presente y no es nulo, entonces intenta calcular una nueva asignación dada la clave y su valor asignado actual.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
También podemos hacer uso de otro método putIfAbsent para poner una clave. Si la clave especificada no está ya asociada a un valor (o está asignada a nulo), este método la asocia al valor dado y devuelve nulo; de lo contrario, devuelve el valor actual.
En caso de que el mapa se comparte a través de las discusiones a continuación, podemos hacer uso de ConcurrentHashMapy AtomicInteger . Del documento:
Un AtomicIntegeres un valor int que puede actualizarse atómicamente. Un AtomicInteger se usa en aplicaciones tales como contadores incrementados atómicamente, y no se puede usar como reemplazo de un Integer. Sin embargo, esta clase sí extiende el Número para permitir el acceso uniforme de herramientas y utilidades que se ocupan de clases basadas en números.
Podemos usarlos como se muestra:
final Map<String,AtomicInteger> map2 = new ConcurrentHashMap<>();
map2.putIfAbsent("A",new AtomicInteger(0));
map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0]
map2.get("B").incrementAndGet(); //[A=0, B=1]
Un punto a tener en cuenta es que estamos invocando getpara obtener el valor de la clave By luego invocando incrementAndGet()su valor, que es, por supuesto AtomicInteger. Podemos optimizarlo ya que el método putIfAbsentdevuelve el valor de la clave si ya está presente:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
En una nota al margen si planeamos usar AtomicLong, entonces, según la documentación bajo alta contención, el rendimiento esperado de LongAdder es significativamente mayor, a expensas de un mayor consumo de espacio. También revise esta pregunta .