如何在只进行一次map查找的情况下增加给定键的值?

11 浏览
0 Comments

如何在只进行一次map查找的情况下增加给定键的值?

假设我有一个地图:

 var inventory = mutableMapOf("apples" to 1, "oranges" to 2)

我想把苹果的数量加1。

然而,这个方法不起作用:

inventory["apples"]!!++ // Error:(9, 4) Variable expected

这个方法也不行:

var apples = inventory["apples"]!!
++apples
println(inventory["apples"]) // prints "1" => the value was not incremented.

这很令人惊讶,因为在Kotlin中,当数字存储在通用对象的实例中时,它们会被包装起来。我不会认为会复制。

似乎唯一的方法是这样的:

var apples = inventory["apples"]!!
++apples
inventory["apples"] = apples
println(inventory["apples"]) 

这用了两个查找地图的操作,而且非常丑陋而冗长。

有没有一种方法可以只用一个查找操作来增加给定键的值?

还有人能解释一下为什么前两种方法不起作用吗?

admin 更改状态以发布 2023年5月23日
0
0 Comments

试试这个:

inventory.computeIfPresent("apples") { _, v -> v + 1 }

前两种方法不起作用,因为当你从映射中检索一个值时,你会得到一个原始类型,例如你的Integer,它是不可变的。当你改变一个整数的值时,你只是把你的变量指向一个新的整数实例,你没有更新你之前指向的那个整数实例。

0
0 Comments

只使用一个get而不使用put来递增值是不可能的。因为Int是不可变的,所以你总是需要在后面执行put操作。 inc()方法(++是它的快捷方式)返回一个新值,它需要被存储在映射中。它不会改变存储的值。

你可以使用

inventory.computeIfPresent("apples") { _, v -> v + 1 }

来将其写成一行,但如果你查看实现,它也会执行get(),然后计算新值并在之后执行put()。所以你可以减少要写的代码行数,但在执行时间上却不能节省CPU周期。

0