Как обновить значение, заданное ключом в Java hashmap?
предположим, что у нас есть HashMap<String, Integer>
в Java.
Как обновить (увеличить) целое значение строкового ключа для каждого существования строки, которую я нахожу?
можно удалить и снова войти в пару, но накладные расходы будут проблемой.
Другой способ - просто поставить новую пару, и старая будет заменена.
в последнем случае, что произойдет, если произойдет столкновение хэш-кода с новым ключом, который я пытаюсь вставить? Правильное поведение hashtable было бы назначить другое место для него или сделать список из него в текущем ведре.
16 ответов
map.put(key, map.get(key) + 1);
должно быть нормально. Он обновит значение для существующего сопоставления. Обратите внимание, что это использует auto-boxing.
Java 8 способ:
можно использовать computeIfPresent
метод и предоставить ему функцию отображения,которая будет вызвана для вычисления нового значения на основе существующего.
например,
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
то обводняться, то можно использовать merge
метод, где 1-значение по умолчанию, а функция увеличивает существующее значение на 1:
words.merge("hello", 1, Integer::sum);
кроме того, есть куча других полезных методов, таких как putIfAbsent
, getOrDefault
, forEach
, etc.
hashmap.put(key, hashmap.get(key) + 1);
метод put
будет заменить значение существующего ключа и создать его, если не существует.
заменить Integer
by AtomicInteger
и позвоните одному из incrementAndGet
/getAndIncrement
методы на нем.
альтернативой является обертывание int
в своем MutableInteger
класс, который имеет increment()
метод, у вас есть только threadsafety озабоченность, чтобы решить еще.
упрощенная Java 8 путь:
map.put(key, map.getOrDefault(key, 0) + 1);
Это использует метод HashMap, который извлекает значение для ключа, но если ключ не может быть извлечен, он возвращает указанное значение по умолчанию (в этом случае "0").
это поддерживается в core Java:хранилище HashMap getOrDefault(ключевой объект, в значение по умолчанию)
@ Matthew'S решение является самым простым и будет работать достаточно хорошо в большинстве случаев.
Если вам нужна высокая производительность, AtomicInteger-лучшее решение ala @BalusC.
однако более быстрое решение (при условии, что безопасность потока не является проблемой) - использовать TObjectIntHashMap который предоставляет метод инкремента (ключа) и использует примитивы и меньше объектов, чем создание AtomicIntegers. например,
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
вы можете увеличить, как показано ниже, но вам нужно проверить наличие, чтобы исключение NullPointerException не бросалось
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
существует ли хэш (с 0 в качестве значения) или он" помещен " на карту при первом приращении? Если он" поставлен " на первом приращении, код должен выглядеть так:
if (hashmap.containsKey(key)) {
hashmap.put(key, hashmap.get(key)+1);
} else {
hashmap.put(key,1);
}
это может быть немного поздно, но вот мои два цента.
если вы используете Java 8, то вы можете использовать computeIfPresent метод. Если значение для указанного ключа присутствует и не равно null, то он пытается вычислить новое сопоставление с учетом ключа и его текущего сопоставленного значения.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
мы также можем использовать другой метод putIfAbsent поставить ключ. Если указанный ключ уже не связывается со значением (или подключенный к нулю), то этот метод связывает его с заданным значением и возвращает null, иначе возвращает текущее значение.
в случае, если карта разделена между потоками, мы можем использовать ConcurrentHashMap
и AtomicInteger. От Дока:
An
AtomicInteger
значение int, которое может быть обновлено автоматически. - AtomicInteger используется в приложениях, таких как атомарно увеличенный счетчики, и не может использоваться в качестве замены для целое. Однако, этот класс расширяет число, чтобы обеспечить единообразный доступ инструментов и утилиты, которые имеют дело с числовыми классами.
мы можем использовать их, как показано ниже:
final Map<String,AtomicInteger> map2 = new ConcurrentHashMap<>();
map2.putIfAbsent("A",new AtomicInteger(0));
map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0]
map2.get("B").incrementAndGet(); //[A=0, B=1]
один момент, чтобы наблюдать, мы призываем get
чтобы получить значение для ключа B
и тогда вызов incrementAndGet()
о его значении, которое, конечно,AtomicInteger
. Мы можем оптимизировать его как метод putIfAbsent
возвращает значение ключа, если уже присутствует:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
на a примечание, если мы планируем использовать AtomicLong тогда в соответствии с документацией при высокой конкуренции ожидаемая пропускная способность LongAdder значительно выше, за счет более высокого потребления пространства. Также проверьте это вопрос.
использовать for
цикл для увеличения индекса:
for (int i =0; i<5; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("beer", 100);
int beer = map.get("beer")+i;
System.out.println("beer " + beer);
System.out ....
}
здесь есть вводящие в заблуждение ответы на этот вопрос, которые подразумевают, что метод Hashtable put заменит существующее значение, если ключ существует, это верно не для Hashtable, а для HashMap. См. Javadoc для HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
поскольку я не могу прокомментировать несколько ответов из-за меньшей репутации, я опубликую решение, которое я применил.
for(String key : someArray)
{
if(hashMap.containsKey(key)//will check if a particular key exist or not
{
hashMap.put(hashMap.get(key),value+1);// increment the value by 1 to an already existing key
}
else
{
hashMap.put(key,value);// make a new entry into the hashmap
}
}
попробуй:
HashMap hm=new HashMap<String ,Double >();
Примечание:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
вы можете изменить ключ или значение в вашем hashmap, но вы не можете изменить оба одновременно.
Integer i = map.get(key);
if(i == null)
i = (aValue)
map.put(key, i + 1);
или
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
Integer-это примитивные типы данных http://cs.fit.edu / ~ryan/java/language/java-data.html, поэтому вам нужно принять его вне, сделать некоторый процесс, тогда положите его назад. если у вас есть значение, которое не является примитивными типами данных, вам нужно только вынуть его, обработать его, не нужно возвращать его в hashmap.