Implement equals with Set

不羁的心 提交于 2019-12-13 15:54:40

问题


I have this class:

private static class ClassA{
int id;
String name;

public ClassA(int id, String name){
    this.id= id;
    this.name = name;
}

@Override
public boolean equals(Object o) {
    return ((ClassA)o).name.equals(this.name);
}   

}

Why this main is printing 2 elements if I am overwriting the method equals in ClassA to compare only the name?

public static void main(String[] args){
    ClassA myObject = new ClassA(1, "testing 1 2 3");
    ClassA myObject2 = new ClassA(2, "testing 1 2 3");    

    Set<ClassA> set = new HashSet<ClassA>();
    set.add(myObject);
    set.add(myObject2);   
    System.out.println(set.size()); //will print 2, but I want to be 1!
}

If I look into the Set Java documentation:

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

So apparently I only have to override equals, however I heard that I have also to override the hashcode, but why?


回答1:


They have different hashes because you didn't override hashCode. This means they were put in two different buckets in the HashSet, so they never got compared with equals in the first place.

I would add

public int hashCode() {
    return name.hashCode();
}

Notice id isn't used in the hashCode because it isn't used in equals either.

(P.S. I'd also like to point out the irony of having an id that isn't used in equals. That's just funny. Usually it's the other way around: the id is the only thing in equals!)




回答2:


Because you didn't override hashCode() as well.

programmers should take note that any class that overrides the Object.equals method must also override the Object.hashCode method in order to satisfy the general contract for the Object.hashCode method. In particular, c1.equals(c2) implies that c1.hashCode()==c2.hashCode().

http://download.oracle.com/javase/6/docs/api/java/util/Collection.html

And:

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()



来源:https://stackoverflow.com/questions/7573055/implement-equals-with-set

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!