当前位置: 首页 > 知识库问答 >
问题:

为什么在Hashmap中没有调用equals方法?

史淳
2023-03-14
import java.util.*;
class Dog {
    public Dog(String n) { name = n; }
    public String name;
    public boolean equals(Object o) {
        System.out.println("equals called..");
        if((o instanceof Dog) &&
                (((Dog)o).name == name)) {
            return true;
        } else {
            return false;
        }
    }
    public int hashCode() {
        System.out.println("hashCodecalled..");
        return name.length(); 
    }
}
class SampleClass {
    public static void main(String[] args) {
        Map<Object, String> m = new HashMap<Object, String>();
        Dog d1 = new Dog("clover");
        m.put(d1, "Dog key");
        d1.name ="arthur";
        System.out.println(m.get(d1));      
    }
}

在上面的代码中,我得到的输出是:

hashCodecalled..
hashCodecalled..
Dog key

在我做 d1.name 之后=“亚瑟”

我期望输出是

hashCodecalled..``
hashCodecalled..
equals called..
null

共有3个答案

贲宜春
2023-03-14

请参见java.util.HashMap。获取方法代码。

它首先检查键是否== e.key然后检查key.equals(e.key)。

在您的代码中,您将同一个实例传递给get方法。所以key == e.key .和key.equals(e.key)不会被执行

public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
      e != null;
      e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}
宗政颖逸
2023-03-14

这个问题以前在这里问过。

根据hashCode方法,它声明“如果两个对象根据equals(Object)方法相等,那么在两个对象的每一个上调用hashCode方法必须产生相同的整数结果。”一般来说,无论何时创建equals方法,都要确保它与返回的hashcode值一致。

HashMap总是在equal方法之前使用hashCode来比较对象。对于您的情况,如果您希望看到equal方法被调用,您可以通过将hashcode值设为常量来模拟哈希冲突场景。(注意:这是一个不错的例子,因为它对性能有很大影响。)

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    Map<Object, String> m = new HashMap<Object, String>();
    Dog d1 = new Dog("clover");
    Dog d2 = new Dog("clover 2");
    m.put(d1, "Dog 1");
    m.put(d2, "Dog 2");
    System.out.println(m.get(d1)); 
}

class Dog {
private String name;
public Dog(String n) {   
    name = n; 
}

@Override
public boolean equals(final Object o) {
    System.out.println("equals called..");
    return true;
}

@Override
public int hashCode() {
    System.out.println("hashCodecalled..");
    return 1; // constant
}}

结果是:

hashCodecalled。。

hashCodecalled。。

等于调用..

hashCodecalled。。

狗 2

最后,您当然需要插入至少两个对象才能使其工作。

沈骞仕
2023-03-14

由于 HashMap 具有您要查找的确切对象,因此它不需要调用 equals 来验证该对象是否正确。

当您从 HashMap 获取对象时,首先会评估 hashCode 以找到正确的存储桶。然后,搜索存储桶。但首先使用 == 比较存储桶中的每个键。如果对象不是正在搜索的对象,则使用 equals

在Java 7中,在< code>HashMap的< code>get方法中,代码的关键部分是

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    return e.value;
 类似资料:
  • 为什么我需要再次使用hmap.put方法? 我的理解是这样的。 假设没有现有的键值对。所以,用 如果我在同一个实例中添加一个字符串,那么hashmap也应该自动更新,对吗?键=>列表对象。如果我添加到列表对象,那么对象引用不应该改变,对吗? 为什么我需要再次使用put方法并这样做?

  • 和都有构造函数来设置初始容量,但提供以确保如果预期插入大量元素,内部数组已经增加。在某些情况下,也可能发生同样的事情。那么为什么没有确保容量的方法来保持存储桶准备就绪?

  • 我编写了一个类,该类重写class Object中的equals(Object)方法,以使用对象的实例值将类类型的对象与类类型的其他对象进行比较。 当我将对象的一个实例作为键放在HashMap中,然后使用一个新的但相同的对象作为键调用映射上的get(object),它返回null。 我尝试将一个新的,相同的对象传递给equals方法,它返回true,所以问题不在于我的比较代码。 从我通过调试收集的

  • 问题内容: 对于以下代码段, 产生的输出是 为什么即使我尝试在fun()中修改a的值也没有修改? a和指针z的地址为何相同但值却不同? const_cast是否有某种未定义的行为? 问题答案: const_cast是否有某种未定义的行为? 是的 ,您的程序包含未定义的行为。 这意味着您不能对它的输出有任何期望。原因由C ++ 11标准的7.1.6.1/4给出: 除了可以声明任何声明的类成员(7.1

  • 我正在创建一个进行线性探测以查找键索引的哈希图。如果键已经在索引中,我想增加它的值,而不是向新索引添加一个。 例如,如果我得到字符串“五,五,五”的字数,我的输出是五1,五1,五1,而不是五3。 我认为一定是我的 containsKey 方法,它使用 get 方法来检查我的密钥是否已在映射中。下面是我的Hashmap.java类。