Java HashMap的replace和put的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35297537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:31:17  来源:igfitidea点击:

Difference between replace and put for HashMap

javahashmap

提问by StudentX

I want to make a histogram by using a HashMap, the key should be the delay, the value the amount of times this delay occurs. I am doubting to use the HashMapreplaceor the HashMapputfunction if an already existing delay has an new occurence.

我想使用 a 制作直方图HashMap,关键应该是延迟,该值是延迟发生的次数。如果已经存在的延迟有新的发生,我怀疑使用HashMapreplaceHashMapput函数。

I did it by this way

我是这样做的

int delay = (int) (loopcount-packetServed.getArrivalTime());
if(histogramType1.containsKey(delay))
{
    histogramType1.replace(delay, histogramType1.get(delay)+1);   
}
else
{
    histogramType1.put(delay, 1);
}

Is this correct? or should I use two times the put function?

这样对吗?还是我应该使用两次 put 函数?

回答by Jean Logeart

In your case, since you first check if the value is contained in the map, using putor replaceleads to the same result.

在您的情况下,由于您首先检查该值是否包含在地图中,因此使用putreplace会导致相同的结果。

You can use either, based on what is more readable to you.

您可以使用任何一种,具体取决于对您来说更易读的内容。

回答by Tunaki

There is absolutely no difference in putand replacewhen there is a current mapping for the wanted key. From replace:

所需密钥的当前映射putreplace何时存在绝对没有区别。来自replace

Replaces the entry for the specified key only if it is currently mapped to some value.

仅当当前映射到某个值时才替换指定键的条目。

This means that if there is already a mapping for the given key, both putand replacewill update the map in the same way. Both will also return the previous value associated with the key. However, if there is no mapping for that key, then replacewill be a no-op (will do nothing) whereas putwill still update the map.

这意味着,如果已经存在,对于给定的键映射,既putreplace将更新以同样的方式在地图。两者都将返回与键关联的先前值。但是,如果该键没有映射,那么replace将是空操作(什么都不做),而put仍会更新映射。



Starting with Java 8, note that you can just use

从 Java 8 开始,请注意您可以只使用

histogramType1.merge(delay, 1, Integer::sum);

This will take care of every condition. From merge:

这将照顾每一个条件。来自merge

If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null.

如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。否则,用给定重映射函数的结果替换关联的值,如果结果为 ,则删除null

In this case, we are creating the entry delay -> 1if the entry didn't exist. If it did exist, it is updated by incrementing the value by 1.

在这种情况下,delay -> 1如果条目不存在,我们将创建条目。如果确实存在,则通过将值增加 1 来更新它。

回答by Thomas

If you look at the sources you can see the following (this is from update 11 but probably hasn't changed much):

如果您查看来源,您可以看到以下内容(来自更新 11,但可能没有太大变化):

replace:

替换

if ((e = getNode(hash(key), key)) != null) {
    V oldValue = e.value;
    e.value = value;
    afterNodeAccess(e);
    return oldValue;
}    

put(internal method putVal):

put(内部方法 putVal):

//some code before this to find the node e (similar to getNode(hash(key)))
if (e != null) { // existing mapping for key
   V oldValue = e.value;
   if (!onlyIfAbsent || oldValue == null)  //onlyIfAbsent is false here
     e.value = value;
   afterNodeAccess(e);
   return oldValue;
}

As you can see, the relevant parts of the code do basically the same thing since onlyIfAbsentis false for putand thus always will replace the value.

如您所见,代码的相关部分基本上做了相同的事情,因为它onlyIfAbsent为假put,因此总是会替换该值。

回答by EdgeCase

You can verify the behavior the others have described, with this:

您可以通过以下方式验证其他人所描述的行为:

public class Main {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.replace("a", "1");
        System.out.println(map.get("a"));

        map.put("a", "1");
        System.out.println(map.get("a"));

        map.replace("a", "2");
        System.out.println(map.get("a"));
    }
}