NOrder
NOrder

Reputation: 2493

How to implement a TreeSet in Java?

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

Answers (4)

Stefan Friesel
Stefan Friesel

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

J.A.I.L.
J.A.I.L.

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

powerMicha
powerMicha

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()andhashCode()` 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

dty
dty

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

Related Questions