0

I'm having trouble getting my head around something I encountered earlier. I have this class named DictionaryOfTranslations, which has a method called add.

The only instance variable this class has is a private HashMap<String, ArrayList<String>> dictionary;.

This is what the add method looks like:

public void add(String word, String translation) {
    this.dictionary.putIfAbsent(word, new ArrayList<>());
    
    ArrayList<String> completed = this.dictionary.get(word);
    completed.add(translation);
    this.dictionary.put(word, completed);
}

The trouble I'm having is to understand why this last line of code: this.dictionary.put(word, completed); is apparently redundant. If I comment this line out, the outcome is exactly the same. My question here is: Why don't you have to specifically have to call the put() method on this hashmap, to add the updated Arraylist to it?

3 Answers3

6

It is redundant because of the putIfAbsent previously. You've already ensured that it's present, in order to get it, so putting it back again doesn't change anything.

Of course, this code is more verbose than it needs to be, and may unnecessarily allocate a new list. Instead:

this.dictionary.computeIfAbsent(word, k -> new ArrayList<>()).add(translation);
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
2

Objects are not passed by value, their references are.

When you use put(), the reference is stored in the HashMap. Similarly, if you use get, you do not get a copy of the list, you get a reference to the same list object.

If you mutate the Map through the reference, you mutate still the same object that is also stored in the map.

Thus, putting it back is simply not needed - you have already changed that very object.

Polygnome
  • 7,639
  • 2
  • 37
  • 57
  • 1
    "Objects are passed by reference in Java." No: ["Java is always pass-by-value."](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – Andy Turner Nov 11 '20 at 11:41
  • I don't think your first line is any clearer after the edit. I'd just drop it entirely. – Andy Turner Nov 11 '20 at 11:47
  • @AndyTurner I like my answers follow the well established writing style of intro/thesis, exposê and conclusion. I think its fine just as it is. – Polygnome Nov 11 '20 at 11:51
1

It is redundant because the Object value you put into the HashMap is shared.

This on the other hand means you cannot do:

// ERROR
translation = new ArrayList<>();
Collection.addAll(translation, "he", "him");
dictionary.put("li", translation);
translation.clear(); // Should have been: translation = new ArrayList<>();
Collection.addAll(translation, "she", "her");
dictionary.put("ŝi", translation);

One has to add a new List every time.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138