Reputation: 2493
I'm implementing a TreeSet which will sort by person's age, but a person will not be saved in set if person's name is equals. I implement equals and hashcode, but this set will save all persons even if they have the same name. I don't know why.
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if(this.getAge()<o.getAge()){
return -1;
}
return this.getAge() == o.getAge()?0:1;
}
@Override
public boolean equals(Object object){
return name.equals(((Person)object).getName());
}
@Override
public int hashCode(){
return name.hashCode();
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void main(String[] args){
Set<Person> set = new TreeSet<Person>();
set.add(new Person("Jack",30));
set.add(new Person("Jack",20));
System.out.println(set);
}
}
Upvotes: 0
Views: 6959
Reputation: 823
You can add
if(name.equals(o.getName())) {
return 0;
}
in the beginning of your compareTo()
function. That way TreeSet can assume a.equals(b)
is equivalent to a.compareTo(b) == 0
and you still get the ordering by age as all names in the set are different.
Upvotes: 3
Reputation: 10794
According to the definition of Set
(of which TreeSet
inherit):
http://docs.oracle.com/javase/6/docs/api/java/util/Set.html:
sets contain no pair of elements e1 and e2 such that e1.equals(e2)
But TreeSet
also must (from: http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html):
the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface
So, your compareTo()
method should check if two Person
are equals()
by name
first, and if they are not, check their age
.
Upvotes: 0
Reputation: 2773
As I understand from the implementation of TreeSet
, it can only contain unique elements. To store these elements in the TreeSet
, the implementation will compare new elements with the existing once using the compareTo()
method.
You code is currently saying - Person is equal by name, but only comparable by age
I suggest that you either change the equals()´,
compareTo()and
hashCode()` method to take name and age into account.
To sort your Person
objects by age, i would recommend a ArrayList
and sort it by a custom Comparator
Upvotes: 0
Reputation: 18998
You can't do that. equals and compareTo have to do "the same thing". That is, if equals returns true, compareTo should return 0 and vica versa.
Upvotes: 2