为什么 v != null ? v++ : 1 与 (v != null ? v : 0) + 1 在递增 HashMap.compute 上的键时不同吗?
Why v != null ? v++ : 1 is not the same as (v != null ? v : 0) + 1 on incrementing a key on 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}
?
我对第一种情况的理解是:
- 如果有键值为
k
的值,从v++
获取结果并放回去,否则用1 填充
而秒的情况是:
- 如果有一个值为 k
k
则保存 v+1
,否则保存 0+1
,这也是 1
为什么在这种情况下 运行 v++
不会导致 v+1
?
因为 (k, v) -> (v != null) ? v++ : 1
在第一次迭代后总是 return 1。
在第一次迭代中,v != null
的计算结果为 false,1
将映射到键 1
。在所有后续调用中,条件将为真并使用 v++
,事实上 post-increment v++
正在使用,1
将是新映射始终保持价值(而不是 2)。
v++
增加 lambda 表达式的局部参数,而不是映射中的值(记住,Java is pass by value)
如果您使用 ++v
而不是 v++
,您也会得到 10。这将起作用,因为新的映射值已经递增(不像 v++
取值然后 然后 递增 v
)
另一方面,(v != null ? v : 0) + 1
总是将 1
添加到当前映射值(它不受 v++
)
行为的影响
我想应用一个计算方法,如果键存在则增加值,否则将 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}
?
我对第一种情况的理解是:
- 如果有键值为
k
的值,从v++
获取结果并放回去,否则用1 填充
而秒的情况是:
- 如果有一个值为 k
k
则保存v+1
,否则保存0+1
,这也是 1
为什么在这种情况下 运行 v++
不会导致 v+1
?
因为 (k, v) -> (v != null) ? v++ : 1
在第一次迭代后总是 return 1。
在第一次迭代中,v != null
的计算结果为 false,1
将映射到键 1
。在所有后续调用中,条件将为真并使用 v++
,事实上 post-increment v++
正在使用,1
将是新映射始终保持价值(而不是 2)。
v++
增加 lambda 表达式的局部参数,而不是映射中的值(记住,Java is pass by value)
如果您使用 ++v
而不是 v++
,您也会得到 10。这将起作用,因为新的映射值已经递增(不像 v++
取值然后 然后 递增 v
)
(v != null ? v : 0) + 1
总是将 1
添加到当前映射值(它不受 v++
)