TreeSet对自定义对象的排序
首先,我们需要对TreeSet的特点进行复习: TreeSet是基于TreeMap实现的存储的元素是不能重复的,默认升序排序的元素。
但是,对于TreeSet的排序,如果是自定义对象的话,是无法进行自动排序的,再运行排序时会发生错误:
Exception in thread "main" java.lang.ClassCastException: _TreeSet.Student cannot be cast to java.lang.Comparable
所以,当我们需要对自定义对象进行排序的时候,就要借助到其他方法了。以下列出两种方法,供自定义对象的排序使用:
类实现Comparable<T>
接口,并重写其compareTo()
方法
这是类似于对基础代码添加新的排序功能,首先对类进行实现接口,并重写其接口方法CompareTo()
在方法中,我们就可以编写自己设定的一个排序逻辑,这样在TreeSet集合进行添加数据时,集合会默认调用此方法来进行对类的排序比较,从而实现排序。
class Student implements Comparable<Student> {
private String studentName;
private int age;
public Student(String studentName, int age) {
this.studentName = studentName;
this.age = age;
}
/**
* geeter和setter方法
*/
@Override
public int compareTo(Student o) {
//年龄降序排序
return o.age - this.age;
}
public static void main(String[] args) {
Student student = new Student("张三", 20);
Student student1 = new Student("李四", 21);
//这里需要注意,如果比较结果=0,则该方法认为对象相等,由于Set集合元素不重复特点,重复元素会被覆盖
Student student2 = new Student("李三", 21);
Student student3 = new Student("赵六", 23);
Set<Student> students2 = new TreeSet<>();
Collections.addAll(students2, student, student1, student2, student3);
System.out.println(students2);
}
}
[Student{studentName='赵六', age=23}, Student{studentName='李四', age=21}, Student{studentName='张三', age=20}]
在新建TreeSet集合时,添加一个Comparator<T>
对象
这样也是一种比较方法,但是不同的是一个是写在集合里,一个是重写类,相对于写在类,写在集合上,不需要修改原来的代码即可定义比较器。当去new Comparator对象时,默认之需要重写一个compare(Student o1, Student o2)
方法,因为在该类中其他类已经default
实现了。
对于两个排序的方法,如果是String类型数据的排序,默认调用的是String的CompareTo(),但是数类型数据只需要直接比较即可。
如果类和集合都拥有Compare的方法,默认就近原则调用集合的Compare方法。
Set<Student> students = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//在这里面写比较逻辑
return ;
}
});