HashMap <k,v>仅由hashCode()

时间:2016-07-12 13:33:40

标签: java dictionary

我刚刚意识到HashMap<K,V>支票k.hashCode() = key.hashCode()k == key

所以,无论是k is "equivalent" to keyk must be == to key还是

是否可以更改此行为以仅使用hashCode()等效?

3 个答案:

答案 0 :(得分:4)

没有hashCode为您进行分组(将元素放入存储桶),而在存储桶中equals用于比较。

检查以下链接:How does a Java HashMap handle different objects with the same hash code?

答案 1 :(得分:2)

  

因此,无论k是否与key“等效”,k必须是==key

不,这是不正确的,因为@KevinWallis已经观察到了。 HashMap使用hashCode()来识别正确的哈希桶,使用 equals() 而不是==来比较属于同一个存储桶的密钥。具有有意义意义的类型,其中不同的实例是等效的,应该通过他们的equals()方法描述,而StringInteger等标准库类型实际上是这样做的。当键是这种类型时,您不必使用相同的对象来从HashMap中检索存储它的值。

另一方面,不具有有意义意义的类型,其中不同的实例是等价的,不应该,并且通常不会覆盖equals()(或hashCode())。从Object继承的实现产生与==运算符相同的结果,这使得使用HashMap键这样的对象或将它们存储在HashSet s中是可行和明智的,至少在某些情况下。

  

是否可以更改此行为以仅使用hashCode()等效?

在这方面无法改变HashMap的行为。如果您能够这样做,那么生成的地图将无法正确履行Map合同。但是,您可以实现您自己的类似于地图的类,或者您可以创建一个包装类来用作替代键类型。

示例键类:

class HashEquivalenceKey<T> {
    private final T object;

    public HashEquivalenceKey(T object) {
        this.object = object;
    }

    public int hashCode() {
        return ((o == null) ? 0 : object.hashCode());
    }

    public boolean equals(Object o) {
        return ((o != null) && (this.hashCode() == o.hashCode()));
    }
}

答案 2 :(得分:1)

  

是否可以更改此行为以仅使用hashCode()等效?

是的,当两个比较对象具有相同的equals时,您可以覆盖hashCode()以返回true。是否有意义是另一回事。

public class SomeKeyClass
{
    boolean equals (Object other)
    {
        if (!(other instanceof SomeKeyClass)) // you can skip this condition too, but it
                                              // makes sense to require the two objects to
                                              // be of the same class in order for them to
                                              // be equal
            return false;
        return hashCode () == other.hashCode ();
    }
}