Difference between replace and put for HashMap

51,098

Solution 1

There is absolutely no difference in put and replace when there is a current mapping for the wanted key. From 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 put and replace will 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 replace will be a no-op (will do nothing) whereas put will still update the map.


Starting with Java 8, note that you can just use

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

This will take care of every condition. From 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.

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

Solution 2

In your case, since you first check if the value is contained in the map, using put or replace leads to the same result.

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

Solution 3

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

replace:

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

put (internal method 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 onlyIfAbsent is false for put and thus always will replace the value.

Solution 4

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"));
    }
}
Share:
51,098

Related videos on Youtube

StudentX
Author by

StudentX

Updated on July 09, 2022

Comments

  • StudentX
    StudentX almost 2 years

    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 HashMap replace or the HashMap put function if an already existing delay has an new occurence. 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?

    • Andy Turner
      Andy Turner over 8 years
      Replace "Replaces the entry for the specified key only if it is currently mapped to some value"
    • StudentX
      StudentX over 8 years
      So I should keep the replace solution ?
    • Thomas
      Thomas over 8 years
      It shouldn't matter in that case since if the element exists it should have the same result as put anyways - since containsKey is used replace is only called if there is a mapping.
    • StudentX
      StudentX over 8 years
      I want the key to stay the same, but the value attached to that key should be incremented by 1, I think using the put function would cause to have 2 times the key with a different value attached to it.
    • Thomas
      Thomas over 8 years
      No, maps don't allow duplicate keys so calling put instead of replace also results in the old value being removed.