理解hashmap(以Arraylist为值)put方法

Understanding hashmap (with Arraylist as value) put method

我无法理解之前遇到的问题。 我有一个名为 DictionaryOfTranslations 的 class,它有一个名为 add.

的方法

此 class 的唯一实例变量是 private HashMap<String, ArrayList<String>> dictionary;

这是添加方法的样子:

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

我遇到的麻烦是理解为什么最后一行代码:this.dictionary.put(word, completed); 显然是多余的。 如果我注释掉这一行,结果是完全一样的。 我的问题是:为什么你不必特别调用这个 hashmap 上的 put() 方法来将更新的 Arraylist 添加到它?

因为之前的putIfAbsent所以是多余的。您已经确保它存在,以便 get 它,因此 put 再次将其调回不会改变任何东西。

当然,这段代码比需要的更冗长,并且可能会不必要地分配一个新列表。相反:

this.dictionary.computeIfAbsent(word, k -> new ArrayList<>()).add(translation);

对象不是按值传递的,它们的引用是。

当您使用 put() 时,reference 存储在 HashMap 中。同样,如果你使用 get,你不会得到列表的 copy,你会得到对 same 列表对象的引用.

如果您通过引用改变地图,您改变的仍然是同样存储在地图中的对象。

因此,根本不需要将其放回原位 - 您已经更改了那个对象。

这是多余的,因为您放入 HashMap 的对象值是共享的。

另一方面,这意味着你不能做:

// 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);

每次都要添加一个新的List。