I have two sample code below. please review them and help me to spot the mistake
SortedSet<String> names = new TreeSet<>();
names.add("ar");
names.add("aj");
names.add("ka");
names.add("ru");
names.add("ti");
System.out.println(names);
SortedSet<String> rangeView;
rangeView = names.subSet("ar", "ti");
System.out.println("flag is "+names.remove("ti"));
System.out.println(rangeView);
System.out.println(names);
The output here is perfectly fine. names.remove("ti"); return true and range view also includes the fromElement and excludes toElement
But if I store an Employee object in the sorted set the remove does not removes the element and also range view shows that fromElement is excluded and toElement is included
here is the code snippet
Employee emp1 = new Employee("aj", LocalDate.parse("2019-09-20"), "57764");
Employee emp2 = new Employee("ar", LocalDate.parse("2016-06-20"), "5324");
Employee emp3 = new Employee("ka", LocalDate.parse("2017-07-21"), "2809");
Employee emp4 = new Employee("ru", LocalDate.parse("2018-08-12"), "2765");
Employee emp5 = new Employee("ti", LocalDate.parse("2018-08-12"), "2762");
SortedSet<Employee> names = new TreeSet<>();
names.add(emp1);
names.add(emp2);
names.add(emp3);
names.add(emp4);
names.add(emp5);
System.out.println(names);
SortedSet<Employee> rangeView;
rangeView = names.subSet(emp3, emp1);
System.out.println("flag is "+names.remove(emp5));
System.out.println(rangeView);
System.out.println(names);
Employee class has name, date of hiring and emp id as fields. it implements Comparable interface and compareTo method compares on hireday and equals case is handled.
the compareTo method is pasted below:
@Override
public int compareTo(Employee second) {
int compareFlag = this.getHireday().compareTo(second.getHireday());
if(compareFlag!=0){
return compareFlag;
}
return this.getEmpid().equals(second.getEmpid()) ? 1:-1;
}
The problem I am facing is:
Your compareTo
method violates the general contract of a Comparable
. Consider emp1
and emp2
in your example. emp1.compareTo(emp2)
will return -1
, but emp2.compareTo(emp1)
will also return -1
.
You can fix this by comparing the ids instead of just checking they are equal, which should make your set work as expected:
@Override
public int compareTo(Employee second) {
int compareFlag = this.getHireday().compareTo(second.getHireday());
if (compareFlag != 0) {
return compareFlag;
}
return this.getEmpid().compareTo(second.getEmpid()); // Here
}