Java中的HashCode和Equals

时间:2013-07-15 20:01:51

标签: java equals hashcode

我理解在类中重写hashcode和equals的基本概念,但是任何人都可以给我一个示例(代码),其中equals将失败只因为hashcode没有被覆盖? 提前谢谢。

2 个答案:

答案 0 :(得分:5)

equals本身不会失败 - 而是依赖于hashCode合同及其与equals的关系的任何事情都可能失败。这是一个例子:

import java.util.*;

final class Person {
    private final String name;

    public Person(String name) {
        // TODO: Nullity prohibition
        this.name = name;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != Person.class) {
            return false;
        }
        return name.equals(((Person)other).name);
    }
}

class Test {
    public static void main(String[] args) throws Exception {
        Person p1 = new Person("Jon");
        Person p2 = new Person("Jon");
        System.out.println(p1.equals(p2)); // true

        Set<Person> people = new HashSet<Person>();
        people.add(p1);
        people.add(p2);
        System.out.println(people.size()); // 2!
    }
}

HashSet假设因为p1.hashCode()p2.hashCode()不同,这两个元素必须不相等,因此两者都可以在集合中。如果hashCode()被适当覆盖,那就不会发生。

同样地,你可以拥有(使用相同的Person类);

Map<Person, String> map = new HashMap<Person, String>();
map.put(p1, "foo");
System.out.println(map.get(p2)); // null

如果两个对象返回相同的哈希码, 将打印出“foo”,因为它们意味着 - 但同样,因为它们没有,HashMap认为有不配。

Eric Lippert's blog post on GetHashCode是对此的一个很好的介绍 - 它是基于C#的,但它同样适用于Java。

答案 1 :(得分:0)

如果你的等于失败,那是因为你实现了等于错误。

以下是如何正确执行此操作: answerWhat issues should be considered when overriding equals and hashCode in Java?

但是,只是为了好玩,这里是一个equals方法的例子,如果没有覆盖hashcode,它会失败:

//NEVER DO THIS
@Override
public boolean equals(Object o){
    ThisObject obj = (ThisObject)o;
    return this.hashCode() == obj.hashCode();
}