Search code examples
javastring-comparisontreeset

TreeSet example


Why the 3rd object is not being added to the treeset here though it is a different one?

import java.util.*;

class Student implements Comparable<Student>{
public String fn,ln;
public Student(String fn,String ln){
    this.fn=fn;
    this.ln=ln;
}

//overiding equals

public boolean equals(Object o) {
    if (!(o instanceof Student))
        return false;
    Student s=(Student) o;
    if(this==s)
        return true;
    if(this.fn.equals(s.fn) && this.ln.equals(s.ln))
        return true;
    return false;
}

//overiding hashcode

public int hashCode() {
    return fn.hashCode()+ln.hashCode();
}


//overiding compareTo

public int compareTo(Student o) {

    return this.fn.compareTo(o.fn);
}
  }

public class Practice {


public static void main(String[] args) {
    Student st1=new Student("Girish","J");
    Student st2=new Student("Master","M");
    Student st3=new Student("Girish","Jay");
    Set S=new TreeSet();

           //adding 3 different student objects

    System.out.println(S.add(st1));
    System.out.println(S.add(st2));
    System.out.println(S.add(st3));
    Iterator sitr=S.iterator();
    while(sitr.hasNext())
    {
        Student stu=(Student) sitr.next();
        System.out.println(stu.fn+" "+stu.ln);
    }


}

 }

Output:

true
true
false
Girish J
Master M

Solution

  • Your comparator function only uses fn:

    public int compareTo(Student o) {
        return this.fn.compareTo(o.fn);
    }
    

    TreeSet only uses ordering comparisons - it doesn't use hashCode() and equals().

    By this comparison, st1 and st3 are equal (s1.compareTo(s3) will return 0) therefore st3 isn't added to the set.

    If you want to maintain the distinction, you should probably compare fn and then use ln if the fn values are the same:

    public int compareTo(Student o) {
        int fnResult = this.fn.compareTo(o.fn);
        return fnResult == 0 ? ln.compareTo(o.ln) : fnResult;
    }