问题
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 equal
ity and include it to compute hashCode
also make sure you follow hashcode and equals contract
来源:https://stackoverflow.com/questions/24374127/hashset-retainall-using-interface