为什么v!=null?v++:1与(v!=null?v:0)+1在HashMap.compute上递增键不同?
我想应用一个计算方法,如果键存在则增加值,否则放 1。
Map<Integer, Integer> map = new HashMap<>();
我不明白为什么
for (int i = 0; i < 10; i++) map.compute(1, (k, v) -> v != null ? v++ : 1);
结果{1=1}
和
for (int i = 0; i < 10; i++) map.compute(1, (k, v) -> (v != null ? v : 0) + 1);
结果{1=10}?
我对第一种情况的理解是:
- 如果有一个带有 key 的值
k,则从中获取结果v++并将其放回原处,否则用 1 填充
而秒的情况是:
- 如果有一个带有 k
ksave的值v+1,否则 save0+1,它也是 1
为什么在这种情况下运行v++不会导致v+1?
回答
因为(k, v) -> (v != null) ? v++ : 1在第一次迭代后总是返回 1。
在第一次迭代中,v != null将评估为 false 并将1映射到 key 1。在所有后续调用中,条件将为真并且v++将被使用,事实上v++正在使用的后增量1将始终是新的映射值(而不是 2)。
v++递增 lambda 表达式的局部参数,而不是映射中的值(请记住,Java 是按值传递的)
如果您使用++v而不是v++,您也会得到 10。这将起作用,因为新的映射值已经递增(不同于v++取值然后递增v)
(v != null ? v : 0) + 1,另一方面,将始终添加1到当前映射的值(它不会受到 的行为的影响v++)
- Well, even simpler is `map.merge(key, 1, (a, b) -> a + b);` or `map.merge(key, 1, Integer::sum);`
THE END
二维码