Увеличение целого числа в HashMap - PullRequest
28 голосов
/ 25 ноября 2010

Должен ли я вернуть объект, а затем вставить новый? Или я могу просто напрямую увеличить?

Integer temp = myMap.get(key);
temp++;
myMap.put(key, temp);

нет способа просто сделать это (это не работает):

myMap.get(key)++;

Ответы [ 11 ]

22 голосов
/ 25 ноября 2010

Это самый короткий код, который выполняет эту работу.

myMap.put(key, myMap.get(key) + 1)

Я думаю, что это не слишком долго.

20 голосов
/ 25 ноября 2010

Вы можете использовать изменяемое целое число, такое как AtomicInteger.

Map<Key, AtomicInteger> myMap = new HashMap<Key, AtomicInteger>();
myMap.get(key).incrementAndGet();

Или использовать Trove4j, который поддерживает примитивы в коллекциях.

TObjectIntHashMap<Key> myMap;
myMap.increment(key); 
19 голосов
/ 11 июля 2015

В Java 8 есть новые методы на Map, которые вы можете использовать с лямбдами для решения этой проблемы. Первая альтернатива, compute:

a.compute(key, (k, v) -> v+1);

Обратите внимание, что это работает, только если хеш инициализирован для всех возможных ключей.

Если это не гарантировано, вы можете изменить приведенный выше код на:

a.compute(key, (k, v) -> v == null ? 1 : v + 1);

Или используйте метод merge (который я бы предпочел):

a.merge(key, 1, (a, b) -> a + b);

Может быть, есть и другие лямбда-методы, о которых я не знаю.

13 голосов
/ 25 ноября 2010

Нужно ли возвращать объект, а затем вставлять новый?

Пока вы используете класс-оболочку Integer yes, потому что он неизменный.Вместо этого вы можете использовать изменяемый класс-обертку, даже тот, который имеет метод increment().Однако при этом вы теряете возможность использовать автобокс и автобокс на значениях.

7 голосов
/ 25 ноября 2010

Вы не можете напрямую увеличить его, потому что он неизменен .Вы должны увеличить его и вернуть новый объект.

Здесь также мешает автобокс.На самом деле то, что происходит, выглядит примерно так:

Integer i1 = getFromMap();
i1 = Integer.valueOf(++ i1.intValue());

Так что здесь ваша ссылка указывает на новый объект.Вы должны поместить этот объект обратно на карту под тем же ключом.

3 голосов
/ 25 ноября 2010

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

2 голосов
/ 04 мая 2014

Если вам нужно сделать это более двух раз, вы бы предпочли создать крошечный класс, такой как:

public class MappedCounter {

    private Map<String, Integer> map = new HashMap<String, Integer>();

    public void addInt(String k, int v) {
        if (!map.containsKey(k))    map.put(k, v);
        else                map.put(k, map.get(k) + v);
    }

    public int getInt(String k) {
        return map.containsKey(k) ? map.get(k) : 0;
    }

    public Set<String> getKeys() {
        return map.keySet();
    }
}
0 голосов
/ 18 сентября 2017

Просто для полноты в Java 8 есть longAdder, который дает некоторые преимущества по сравнению с AtomicInteger (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html)

final Map<WhatEver, LongAdder> result = new HashMap<>();
result.get(WhatEver).increment();
0 голосов
/ 02 ноября 2016

Это должно работать

        // If the key you want to add does not exist then add it as a new key
        // And make the value 1
        if (map.get(key) == null) {
            map.put(key, 1);
        } else {
            // If the key does exist then replace the key's value with it's
            // Original value plus one
            map.put(key, map.get(key) + 1);
        }
0 голосов
/ 18 мая 2016

Я использую приведенный ниже код, и он работает, но в начале вам нужно определить BiFunction, описывающий, что операция увеличивается на 1.

public static Map<String, Integer> strInt = new HashMap<String, Integer>();

public static void main(String[] args) {
    BiFunction<Integer, Integer, Integer> bi = (x,y) -> {
        if(x == null)
            return y;
        return x+y;
    };
    strInt.put("abc", 0);


    strInt.merge("abc", 1, bi);
    strInt.merge("abc", 1, bi);
    strInt.merge("abc", 1, bi);
    strInt.merge("abcd", 1, bi);

    System.out.println(strInt.get("abc"));
    System.out.println(strInt.get("abcd"));
}

вывод

3
1
...