假设我们在Java中有一个HashMap<String, Integer>。

我如何更新(增量)字符串键的整数值为我找到的字符串的每个存在?

人们可以删除并重新输入配对,但开销将是一个问题。 另一种方法是只放一双新的,旧的就会被替换掉。

在后一种情况下,如果hashcode与我试图插入的新键发生冲突,会发生什么?哈希表的正确行为是为它分配一个不同的位置,或者在当前桶中对它进行列表。


将Integer替换为AtomicInteger,并调用其中一个incrementAndGet/getAndIncrement方法。

另一种方法是在你自己的MutableInteger类中包装一个int,这个类有一个increment()方法,你只需要解决线程安全问题。


map.put(key, map.get(key) + 1);

应该没问题。它将更新现有映射的值。注意,这使用了自动装箱。在map.get(key)的帮助下,我们得到相应的key值,然后您可以根据您的需求进行更新。在这里,我正在更新,使value增加1。


@Matthew的解决方案是最简单的,在大多数情况下都会表现得很好。

如果你需要高性能,AtomicInteger是一个比@BalusC更好的解决方案。

然而,一个更快的解决方案(如果线程安全不是一个问题)是使用TObjectIntHashMap,它提供了一个增量(键)方法,使用原语和比创建AtomicIntegers更少的对象。如。

TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");

hashmap.put(key, hashmap.get(key) + 1);

put方法将替换现有键的值,如果不存在则创建该键。


使用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 ....

}

Try:

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中的键或值,但不能同时更改两者。


您可以像下面这样递增,但您需要检查是否存在,以便不会抛出NullPointerException

if(!map.containsKey(key)) {
 p.put(key,1);
}
else {
 p.put(key, map.getKey()+1);
}

散列是否存在(以0为值)或者它是否在第一个增量上“放置”到映射中?如果它是“put”在第一个增量上,代码应该是这样的:

if (hashmap.containsKey(key)) {
    hashmap.put(key, hashmap.get(key)+1);
} else { 
    hashmap.put(key,1);
}

对于这个问题,有一些误导性的回答暗示,如果键存在,Hashtable put方法将替换现有的值,这对于Hashtable不是正确的,而对于HashMap是正确的。HashMap参见Javadoc http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29


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等。


可能有点晚了,但这是我的意见。

如果你使用的是Java 8,那么你可以使用computeIfPresent方法。如果指定键的值存在且非空,则在给定键及其当前映射值的情况下,它将尝试计算一个新的映射。

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),则该方法将其与给定值关联并返回null,否则返回当前值。

如果映射是跨线程共享的,那么我们可以使用ConcurrentHashMap和AtomicInteger。医生说:

AtomicInteger是一个int值,可以被原子地更新。一个 AtomicInteger用于原子递增等应用程序 计数器,不能用作Integer的替换。然而, 这个类扩展了Number以允许工具和工具的统一访问 处理基于数值的类的实用程序。

我们可以如下所示使用它们:

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的值,然后对其值(当然是AtomicInteger)调用incrementAndGet()。我们可以通过putIfAbsent方法来优化它,如果键已经存在,则返回键的值:

map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]

另一方面,如果我们计划使用AtomicLong,那么根据高争用的文档,LongAdder的预期吞吐量将显著提高,但代价是更高的空间消耗。也检查这个问题。


简化的Java 8方式:

map.put(key, map.getOrDefault(key, 0) + 1);

它使用HashMap的方法来检索键的值,但如果无法检索键,则返回指定的默认值(在本例中为'0')。

HashMap<K,V> getOrDefault(对象键,V defaultValue)


一句话解决方案:

map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);

Integer i = map.get(key);
if(i == null)
   i = (aValue)
map.put(key, i + 1);

or

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。


由于我不能评论一些答案,由于较少的声誉,我会张贴一个解决方案,我应用。

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
   }
}

没有NullPointerException的更干净的解决方案是:

map.replace(key, map.get(key) + 1);

使用Java8内置函数“computeIfPresent”

例子:

public class ExampleToUpdateMapValue {

    public static void main(String[] args) {
        Map<String,String> bookAuthors = new TreeMap<>();
        bookAuthors.put("Genesis","Moses");
        bookAuthors.put("Joshua","Joshua");
        bookAuthors.put("Judges","Samuel");

        System.out.println("---------------------Before----------------------");
        bookAuthors.entrySet().stream().forEach(System.out::println);
        // To update the existing value using Java 8
        bookAuthors.computeIfPresent("Judges", (k,v) -> v = "Samuel/Nathan/Gad");

        System.out.println("---------------------After----------------------");
        bookAuthors.entrySet().stream().forEach(System.out::println);
    }
}