Как увеличить значение данного ключа только с одним поиском карты? - PullRequest
0 голосов
/ 14 декабря 2018

Допустим, у меня есть карта:

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

, и я хочу увеличить количество яблок на единицу.

Однако это не работает:

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"]) 

, который использует два поиска на карте и очень уродливи длинный.

Есть ли способ увеличить значение данного ключа, используя только один поиск?

Кроме того, кто-то может объяснить, почему первые два метода не работают?

Ответы [ 4 ]

0 голосов
/ 14 декабря 2018

Метод computeIfPresent в java.util.HashMap делает только один поиск .Таким образом, вы можете использовать:

var inventory = hashMapOf("apples" to 1, "oranges" to 2)
inventory.computeIfPresent("apples") { _, v -> v + 1 }  // Only 1 lookup!

Примечание: это деталь реализации.Он выполняет один поиск в текущей версии Kotlin (1.3.11), используя конкретную реализацию Java (Oracle HotSpot 11.0.1).Другие конфигурации могут или не могут использовать другие способы.

0 голосов
/ 14 декабря 2018

Невозможно увеличить значение только с одним get и без put.Вы всегда должны сделать put впоследствии, потому что Int является неизменным.Метод inc() (ярлык для этого ++) возвращает новое значение, которое необходимо сохранить на карте.Он не изменяет сохраненное значение.

Вы можете использовать

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

, чтобы записать его в одну строку, но если вы посмотрите на реализацию, она также выполнит get(), а затем вычислитновое значение и сделайте put() потом.Таким образом, вы можете сохранить строку кода, которую вам нужно написать, но вы не будете экономить циклы ЦП во время выполнения.

0 голосов
/ 14 декабря 2018

Поскольку целые числа упакованы в карты, Integer является примитивным классом-оберткой, а примитивные классы-обертки являются неизменяемыми в Java , кажется, что вы хотите изменить неизменяемый объект, что, к сожалению,невозможно, по крайней мере, никакими обычными или рекомендованными способами

Взгляните на Самый эффективный способ увеличения значения Map в Java , где есть несколько предложений о том, как повысить производительность приращения целочисленных значений в картах, а также один явноРеализация желаемого поведения через класс-оболочку MutableInt, который также оказывается самым быстрым (~ 20% быстрее, чем базовый уровень).

0 голосов
/ 14 декабря 2018

Попробуйте это:

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

Первые два метода не работают, потому что когда вы извлекаете значение из карты, вы получаете примитивный тип, в вашем случае Integer, который является неизменным.Когда вы изменяете значение Integer, вы просто указываете свою переменную на новый экземпляр Integer, вы не обновляете тот экземпляр Integer, на который ранее указывали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...