【问题标题】:Understanding hashmap (with Arraylist as value) put method了解hashmap(以Arraylist为值)put方法
【发布时间】:2020-11-11 11:36:29
【问题描述】:

我无法理解之前遇到的事情。 我有一个名为DictionaryOfTranslations 的类,它有一个名为add 的方法。

这个类唯一的实例变量是private HashMap<String, ArrayList<String>> dictionary;

这是 add 方法的样子:

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
  • completed 是对字典中的 ArrayList 的引用,您正在直接修改它

标签: java arraylist hashmap


【解决方案1】:

由于之前的putIfAbsent,它是多余的。您已经确保它存在,以便get 它,所以put再次返回它不会改变任何东西。

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

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

【讨论】:

    【解决方案2】:

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

    当您使用put() 时,reference 存储在 HashMap 中。同样,如果您使用get,您不会获得列表的副本,而是获得对相同列表对象的引用。

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

    因此,根本不需要把它放回去 - 你已经改变了那个对象。

    【讨论】:

    • "对象在 Java 中通过引用传递。"没有:"Java is always pass-by-value."
    • 我认为您的第一行在编辑后没有更清晰。我会完全放弃它。
    • @AndyTurner 我喜欢我的回答遵循介绍/论文、公开和结论的成熟写作风格。我认为它就这样很好。
    【解决方案3】:

    这是多余的,因为你放入 HashMap 的 Object 值是共享的。

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

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

    每次都必须添加一个新列表。

    【讨论】:

      猜你喜欢
      • 2022-12-17
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 2019-09-23
      相关资源
      最近更新 更多