需求背景:刷题的时候,需求要做排序,并且不能去重,然后写了个 bug。
所以我用了TreeSet,并且把要排序的内容封装成对象放到集合中,对象实现了compareTo方法。由于我实现的compareTo方法把=0的情况和<0的情况合并了,所以达到了排序且没有去重的效果,但是后面在调用remove方法的时候失败了。
先上一段测试代码:
import java.util.TreeSet;
public class test {
static class Student implements Comparable{
public Integer age;
public String name;
public Student(Integer age, String name) {
this.age = age;
this.name = name;
}
@Override
public int compareTo(Object o) {
if (this.age-((Student)o).age<=0)
return -1;
else
return 1;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + ''' +
'}';
}
}
public static void main(String[] args) {
TreeSet set=new TreeSet();
Student a = new Student(5, "张三");
Student b = new Student(6, "张四");
Student c = new Student(10, "张五");
Student d = new Student(10, "法外狂徒");
System.out.println("张三"+set.add(a));
System.out.println("张四"+set.add(b));
System.out.println("张五"+set.add(c));
System.out.println("法外狂徒"+set.add(d));
System.out.println("删除法外狂徒"+set.remove(d));
for (Student student : set) {
System.out.println(student);
}
}
}
得到了下面的结果,可以看到删除对象失败了,于是我跳到源码去定位问题:
首先treeSet会调用TreeMap的remove方法
再进入getEntry方法,结果便明朗了,原来remove方法也调用了我实现的compareTo,并且由于我的方法=0和<0的比较情况都返回的-1,所以压根走不到最后一个else,整个方法便返回了null。
最后总结:实现比较器接口的compare方法需谨慎。不然JAVA原生集合自带的一些方法可能不好使了。



