问题
I have some code where I try to use the HashSet.retainAll() function.
In the example code below, the HashSet contains the interface IPerson, but the equals functions in object Person is never reached. I have even tried to expose the equals function in the interface and several other things. I feel I have tried everything. How can I make retainAll() use my implemented equal function?
class Person implements IPerson {
private String name;
public Person(String name){
this.name = name;
}
@Override
public boolean equals(Object obj){
System.out.println("calling equals");
return super.equals(Object obj);
}
}
HashSet<IPerson> persons1 = new HashSet<IPerson>();
persons1.add(new Person("Jane"));
persons1.add(new Person("Joel"));
persons1.add(new Person("Joe"));
HashSet<IPerson> persons2 = new HashSet<IPerson>();
persons2.add(new Person("Jane"));
persons2.add(new Person("Joel"));
persons1.retainAll(persons2);
// expect sysout from Person.equals()
System.out.println(persons1.size());
// prints 0
回答1:
You need to override hashCode because the hashset uses the hashcode to find the right 'bucket' first and only calls equals after it finds something in it. That's why your equals method is never called. (if you don't override the hashcode method, it gives every new object a different hashcode, so even if you call new Person("name") twice with the same name they won't have the same hashcode)
回答2:
you need to consider name to check equality and include it to compute hashCode also make sure you follow hashcode and equals contract
来源:https://stackoverflow.com/questions/24374127/hashset-retainall-using-interface