Java 在hashmap中给定一个键,如何更新一个值?

Java 在hashmap中给定一个键,如何更新一个值?,java,key,hashmap,Java,Key,Hashmap,假设我们在Java中有一个HashMap 如何为找到的字符串的每个存在更新(递增)字符串键的整数值 可以删除并重新输入该对,但开销将是一个问题。 另一种方法是把新的一对放进去,然后把旧的换掉 在后一种情况下,如果哈希代码与我尝试插入的新密钥发生冲突,会发生什么情况?哈希表的正确行为是为它指定一个不同的位置,或者在当前存储桶中从中列出一个列表。替换整数,并调用其中一个递增和get/getAndIncrement方法 另一种方法是将int封装在您自己的MutableInteger类中,该类具有inc

假设我们在Java中有一个
HashMap

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

可以删除并重新输入该对,但开销将是一个问题。
另一种方法是把新的一对放进去,然后把旧的换掉


在后一种情况下,如果哈希代码与我尝试插入的新密钥发生冲突,会发生什么情况?哈希表的正确行为是为它指定一个不同的位置,或者在当前存储桶中从中列出一个列表。

替换
整数
,并调用其中一个
递增和get
/
getAndIncrement
方法

另一种方法是将
int
封装在您自己的
MutableInteger
类中,该类具有
increment()
方法,您只需要解决线程安全问题

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

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

@Matthew的解决方案是最简单的,在大多数情况下都能很好地执行

如果您需要高性能,AtomicInteger是更好的解决方案ala@BalusC

但是,一个更快的解决方案(前提是线程安全不是问题)是使用增量(键)方法,使用原语和比创建原子整数更少的对象。e、 g

TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
tobjectnthashmap=new-tobjectnthashmap()
地图增值(“aaa”);

方法
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 ....

}
for(int i=0;i尝试:


您可以更改hashmap中的键或值,但不能同时更改两者。

您可以按如下方式递增,但需要检查是否存在NullPointerException,以便不会引发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);
}

对于这个问题,这里有一些误导性的答案,这意味着如果键存在,Hashtable put方法将替换现有值。这对于Hashtable不是这样,而是对于HashMap。请参阅Javadoc for HashMap

Java 8-way: 您可以使用
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"));

此外,还有许多其他有用的方法,例如
putIfAbsent
getOrDefault
forEach
,等等。

可能有点晚了,但这是我的两分钱

如果您使用的是Java 8,那么您可以使用方法。如果指定键的值存在且不为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]
需要观察的一点是,我们正在调用
get
来获取键
B
的值,然后调用
incrementAndGet()
来获取其值,当然,该值是
AtomicInteger
。我们可以对其进行优化,因为方法
putIfAbsent
返回键的值(如果已经存在):

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

另一方面,如果我们计划在高竞争条件下按照文档使用,则的预期吞吐量将显著提高,而以更高的空间消耗为代价。请检查这一点。

简化的Java 8方式:

map.put(key, map.getOrDefault(key, 0) + 1);
这使用HashMap方法来检索键的值,但如果无法检索该键,它将返回指定的默认值(在本例中为“0”)

这在核心Java中得到支持:

单线解决方案:

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


Integer是基本数据类型,所以您需要将其取出,进行一些处理,然后将其放回。如果您有一个不是基本数据类型的值,您只需要将其取出,处理它,无需将其放回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内置函数“ComputeiPresent”

例如:

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);
    }
}
公共类ExampleToUpdateMapValue{
公共静态void main(字符串[]args){
Map bookAuthors=new TreeMap();
书的作者。put(“创世记”,“摩西”);
书的作者。把(“约书亚”、“约书亚”);
书的作者。put(“法官”、“塞缪尔”);
System.out.println(“------------------------在--------------------之前”);
bookAuthors.entrySet().stream().forEach(System.out::println);
//使用Java 8更新现有值
书籍作者:computeIfPresent(“法官”(k,v)->v=“塞缪尔/内森/加德”);
System.out.println(“-------------------在--------------------之后”);
bookAuthors.entrySet().stream().forEach(System.out::println);
}
}

事实上,这是最健壮和可扩展的企业解决方案。@Lavir,这是一个不错的解决方案,但不知道它是如何最健壮和可扩展的。相反,atomicinteger更具可扩展性。这假设密钥存在,对吧?如果它不存在,我会得到nullPointer异常。对于Java 8,使用
getO可以很容易地避免这种情况rDefault
,例如:
map.put(key,count.getOrDefault(key,0)+1);
@Martin..map.put(key,map.getOrDefault(key,0)+1)AtomicInteger是一个可变整数,但它是内置的。我严重怀疑编写自己的可变整数是一个更好的主意。自定义
MutableInteger
更好,因为
AtomicInteger
使用
volatile
,这有开销。我会使用
int[1]
而不是
MutableInteger
@Oliv:不是并发的。@BalusC但是,volatile写入更昂贵。它会使
map.put(key, map.getOrDefault(key, 0) + 1);
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);
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
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
   }
}
map.replace(key, map.get(key) + 1);
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);
    }
}