Shubham Kharde Shubham Kharde - 5 months ago 15
Java Question

Why can't TreeSet have student ages similar when the whole student object is unique?

I have a datatype

StudentSet
. It accepts name and age. When I add this to
TreeSet
, students with similar ages are not added. I know that
TreeSet
only add uniques, but i have different name for student so as a whole isn't the
StudentSet
unique? I want to know the reason behind this.

Following is my code

import java.util.Comparator;
import java.util.TreeSet;

public class StudentSet implements Comparable<StudentSet> {
String name;
int age;

public StudentSet(String name, int age) {
super();
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Student[Name= " + name + "," + " Age= " + age + "]";
}


public static void main(String[] args) {
TreeSet<StudentSet> set = new TreeSet<>();
set.add(new StudentSet("xyz", 21));
set.add(new StudentSet("abc", 23));
set.add(new StudentSet("xyxyxr", 24));
System.out.println(set.add(new StudentSet("aaaaaa", 20))); //prints false
System.out.println(set.add(new StudentSet("bbbbbb", 20))); //prints false
System.out.println(set.add(new StudentSet("cccc", 20))); //prints false

TreeSet<StudentSet> sort = new TreeSet<>(new Comparator<StudentSet>() {
@Override
public int compare(StudentSet o1, StudentSet o2) {
return o1.name.compareTo(o2.name);
}
});

sort.addAll(set);
System.out.println("Sorting According to Name\n");
for (StudentSet s : sort) {
System.out.println(s);
}
System.out.println();

sort = new TreeSet<>(new Comparator<StudentSet>() {
@Override
public int compare(StudentSet o1, StudentSet o2) {
return o1.compareTo(o2);
}
});

System.out.println("Sorting According to Age\n");
sort.addAll(set);
for (StudentSet s : sort) {
System.out.println(s);
}
System.out.println();

sort = new TreeSet<>(new Comparator<StudentSet>() {
@Override
public int compare(StudentSet o1, StudentSet o2) {
int lastIndex1 = o1.name.lastIndexOf(" ");
int lastIndex2 = o2.name.lastIndexOf(" ");

String lastName1 = o1.name.substring(lastIndex1);
String lastName2 = o2.name.substring(lastIndex2);
if (lastName1.equals(lastName2)) {
return o1.name.compareTo(o2.name);
} else {
return lastName1.compareTo(lastName2);
}
}
});

System.out.println("Sorting According to Last Name\n");
sort.addAll(set);
for (StudentSet s : sort) {
System.out.println(s);
}
}

@Override
public int compareTo(StudentSet o) {
return ((Integer) this.age).compareTo(o.age);
}
}


Update:



The main culprit was that i have set the
compareTo()
method in
StudentSet
to compare ages, which the
TreeSet
internally uses to both compare and check for uniqueness.

Here is my corrected and satisfied code.

@Override
public int compareTo(StudentSet o)
{
int i = Integer.compare(this.age, o.age);
if (i == 0)
return this.name.compareTo(o.name);
else
return i;
}

Answer

Redefine your compareTo method, StudentSet is your own custom object, so by implementing Comparable interface, you are telling compiler to add to TreeSet following your implementation.

The implementation below say, if age of two or more StudentSet are same, then they are unique equal.

@Override
public int compareTo(StudentSet o)
{
    return ((Integer) this.age).compareTo(o.age);
}

Modify the implementation as below,

@Override
    public int compareTo(StudentSet o)
    {
         int i = ((Integer) this.age).compareTo(o.age);
            if (i == 0)
                return this.name.compareTo(o.name);
            else
               return i;
    }

The above will check for both Age and Name and if same, the your object is unique.

Comments