java - 修改HashMap key之一

标签 java dictionary hashmap

package always.confusing;

import java.util.HashMap;
import java.util.Map;

class Dog {
public Dog(String n) { name = n; }
public String name;
public boolean equals(Object o) {
    if((o instanceof Dog) &&
            (((Dog)o).name == name)) {
        return true;
    } else {
        return false;
    }
}
public int hashCode() {return name.length(); }
}

public class QustionToaAsk {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Map<Object, Object> m = new HashMap<Object, Object>();

    Dog d1 = new Dog("clover");
    m.put(d1, "Dog key");

    System.out.println("**" + m.get(new Dog("clover")));

    d1.name = "magnolia";
    System.out.println("state after magnolia");
    System.out.println(m.get(new Dog("magnolia")));
    System.out.println(m.get(d1)); // #1
    System.out.println("**" + m.get(new Dog("clover")));///????????
    System.out.println("size:" + m.size());

    d1.name = "clover";
    System.out.println("\nstate after clover");
    System.out.println(m.get(new Dog("clover"))); // #2
    System.out.println(m.get(d1));
    System.out.println("size:" + m.size());

    d1.name = "arthur";
    System.out.println("\nstate after arthur");
    System.out.println(m.get(new Dog("arthur")));
    System.out.println(m.get(d1));
    System.out.println("size:" + m.size());
}

}

输出:

**Dog key

Jade 兰花后的状态

null

null

**null

size:1

三叶草之后的状态

Dog key

Dog key

size:1

亚瑟之后的状态

Dog key

Dog key

size:1

为什么第一组打印无法获取具有三叶草和木兰内容的 Dog 对象 但在其他两组中它是否符合预期?

即为什么在尝试更改为“magnolia”后,为什么下一个 get()(仍然使用正确的对象,即 get(new Dog("clover"))))无法获取值“Dog key”?更改为 equals.. 后输出仍然相同 –

//忽略

最佳答案

您需要了解 HashMap 的工作原理。

当您将一个键放入包含 N 个存储桶的 HashMap 中时,将使用该键的 hashCode 来查找适当的存储桶。然后使用 equals() 将存储桶中包含的每个键与添加的键进行比较,以了解该键是否已在映射中。

类似地,当获取某个键的值时,首先使用 hashCode() 查找合适的存储桶,然后使用 equals() 将该存储桶中的每个键与传递给 get() 的键进行比较。

在使用 HashMap 时,您正在做两件不应该做的事情:

  1. 将 key 存储在 map 中后对其进行修改。这会修改其 hashCode,并导致无法在适当的存储桶中搜索该键。有点像你把所有红色硬币放在一个红色抽屉里,然后将其中一把 key 重新漆成蓝色。显然,如果您随后搜索蓝色硬币,您将在蓝色抽屉中搜索它们,而不是在存储硬币的红色抽屉中搜索它们,因为它最初是红色的。
  2. 使用使许多键具有相同值的算法来实现 hashCode()。 “clover”和“arthur”就是这种情况,它们具有相同的长度,因此在您的实现中具有相同的 hashCode() 。另一方面,“magnolia”没有相同的 hashCode()。

鉴于上述内容,您应该能够理解为什么您的代码会这样工作。只要在纸上画出每个操作发生的情况,您就会明白。

关于java - 修改HashMap key之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24149035/

相关文章:

c# - 填充字典中出现 KeyNotFoundException

java - Java 中 HashMap 的奇怪行为

java - 在java中搜索列表中对象的最快方法

java - 如何用正则表达式替换最后一个字符为特殊字符的单词

java - 写入带有重音字符的文件

java - WildFly 9 发送邮件两次

java - 什么是 Swift 字典的 Android Java 等价物?

c# - 如何使用迭代器获取字典的键/值?

Java:使用 HashMap ,检索所有值和调用方法

java - 将 onClick 函数添加到 ActionBar 中的项目 (Android)