概念
(对于自定义类型如何进行排序?)
TreeSet集合对自定义类型的对象排序的方法
方法一 类实现Comparable接口,重写比较规则。
public class Teacher implements Comparable<Teacher>{
private String name;
private int age;
private double salary;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}'+"\n";
}
//t2.compareTo(t1)
//t2 == this 比较者
//t1 == o 被比较者
//规则1 如果你认为左边大于右边 请返回正整数
//规则2 如果你认为左边小于右边 请返回负整数
//规则3 如果你认为左边等于右边 请返回0
//默认会升序排序
@Override
public int compareTo(Teacher o) {
// if(this.getAge() > o.getAge()) return 1;
// if(this.getAge() < o.getAge()) return -1;
// return 0;
//标准写法
return this.getAge() - o.getAge(); //升序排序
//return o.getAge() - this.getAge(); 降序排序
}
}
方法二 集合自定义Comparator比较器对象,重写比较规则。
{
public static void main(String[] args) {
//目标:搞清楚TreeSet集合对于自定义对象的排序
Set<Teacher> teachers = new TreeSet<>(new Comparator<Teacher>() {
@Override
public int compare(Teacher o1, Teacher o2) {
//return o2.getAge() - o1.getAge();
return Double.compare(o1.getSalary(), o2.getSalary());//薪水升序
}
});// 排序 不重复 无索引
teachers.add(new Teacher("小明", 18, 5000));
teachers.add(new Teacher("小红", 19, 6000));
teachers.add(new Teacher("小刚", 20, 7000));
teachers.add(new Teacher("小刚", 20, 7000));
System.out.println(teachers);//会报错,因为TreeSet集合是一定会按照自己的排序规则进行排序的,但是现在集合里的元素不符合它的排序规则,所以会报错
}
}
比较方法的三种方式
1、用if的形式去比较,很安全但是代码low
if(this.getAge() > o.getAge()) return 1;
if(this.getAge() < o.getAge()) return -1;
2、用相减的形式去比较,高级点,但是不使用于比较小数。
因为被重写的compare方法一般都是int返回类型的,所以double直接报错。 注意:也不要强转,会出错。例如0.3-0.1被强转成int类型 结果是0。这会被java的默认比较规则视为它两是相等的。
return this.getAge() - o.getAge();
return (int)(this.getAge() - o.getAge());
3、最好的方法是调用Double类的compare方法,高级,也支持小数。
return Double.compare(o1.getSalary(), o2.getSalary());
注意点
1、为什么TreeSet集合不支持自定义类型的对象排序,因为TreeSet集合是会按照自己的默认排序规则进行排序的,但是现在集合里的元素不符合它的排序规则,所以会报错
2、如果既有类实现接口重写方法制定规则,又有集合自定义Comparator比较器对象重写规则,那么优先使用后者的规则
3、TreeSet是不重复的。它会基于比较规则,确定两个元素是否相等,相等的话,就去掉一个,来去重。
可以通过if语句中不比较两个元素相同并且第三行代码不返回0,来保证不去重。
if(this.getAge() > o.getAge()) return 1
if(this.getAge() < o.getAge()) return -1;
return 1或-1;
4、在往TreeSet集合里添加第1个之后的对象时,都会隐式调用比较大小的方法
Set<Teacher> teachers = new TreeSet<>(new Comparator<Teacher>() {
teachers.add(new Teacher("小明", 18, 5000));
teachers.add(new Teacher("小红", 20, 6000));
//隐式的代码
t2代表后添加的对象,t1代表先添加的代码
t2.compareTo(t1)