i_am_zero..
6
可能会有点晚,但这是我的两分钱.
如果您使用的是Java 8,则可以使用computeIfPresent方法.如果指定键的值存在且非null,则它会尝试计算给定键及其当前映射值的新映射.
final Map map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
我们还可以使用另一个方法putIfAbsent来放一个键.如果指定的键尚未与值关联(或映射为null),则此方法将其与给定值相关联并返回null,否则返回当前值.
如果地图是跨线程共享的,那么我们可以使用ConcurrentHashMap和AtomicInteger.来自doc:
An AtomicInteger是一个可以原子方式更新的int值.AtomicInteger用于诸如原子递增计数器的应用程序中,不能用作Integer的替代.但是,此类确实扩展了Number,以允许通过处理基于数字的类的工具和实用程序进行统一访问.
我们可以使用它们如图所示:
final Map 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]
需要注意的一点是,我们正在调用get获取key的值B,然后调用incrementAndGet()其值,这当然是AtomicInteger.我们可以优化它,因为方法putIfAbsent返回密钥的值(如果已经存在):
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
另外,如果我们计划使用AtomicLong,那么根据高争用的文档,LongAdder的预期吞吐量会显着提高,但会占用更高的空间消耗.还要检查这个问题.