很多类里面有compareTo方法,这个方法是源于comparable接口里。Arrays可以调用sort方法,前提是这个数组类型实现了comparable方法。
比如下面的代码是不对的,因为Student类并没有实现comparable接口,所以数组不知道明确的比较规则而报错:
public class Main { public static void main(String[] args){ Student[] stu = {new Student(), new Student()}; Arrays.sort(stu); } static class Student{ } }
现在为Student类里实现Comparable接口:
static class Student implements Comparable<Student>{ int age; public Student(int age) { this.age = age; } @Override public int compareTo(Student o) { return age - o.age; } @Override public String toString() { return "Student{" + "age=" + age + '}'; } }
有了比较的方法,就可以进行排序;
java
public static void main(String[] args){
TreeSet set = new TreeSet<>();
set.add(new Student(10));
set.add(new Student(16));
System.out.println(set);
}

java
public static void main(String[] args){
Student[] arr = {new Student(6),new Student(9),new Student(8)};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}

此外,如果在Student类并没有实现Comparable方法,也可以在调用Arrays.sort()的时候使用lambda表达式去添加。比如:
public static void main(String[] args){ Student[] arr = {new Student(6),new Student(9),new Student(8)}; Arrays.sort(arr, (s1,s2)->s1.age-s2.age); //比较方法 System.out.println(Arrays.toString(arr)); } static class Student{ int age; public Student(int age) { this.age = age; } @Override public String toString() { return "Student{" + "age=" + age + '}'; } }

在TreeSet里面,也可以定义比较方法:
TreeSet<Student> stu = new TreeSet<>((s1,s2)->s1.age - s2.age); stu.add(new Student(6)); stu.add(new Student(9)); System.out.println(stu);
此外,可以单独写一行定义comparator,这样就直接传入:(reversed是在原来的基础上取反)
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age; TreeSet<Student> stu = new TreeSet<>(comparator.reversed());
现在,我们除了需要比较年龄来排序,还要一个额外的姓名排序(即年龄一样,按照姓名排序),使用thenComparing(),下面是Student类:
static class Student{ int age; String name; public Student(int age,String name) { this.age = age; this.name = name; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
下面是主文件:
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age; TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing((s1,s2)->s1.name.compareTo(s2.name))); stu.add(new Student(6,"hxl")); stu.add(new Student(6,"lhw")); stu.add(new Student(8,"520")); System.out.println(stu);

此外,thenComparing也可以:
Comparator<Student> comparator = (s1,s2)->s1.age - s2.age; TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing( s->s.name, (n1,n2)->n1.compareTo(n2)) );
thenComparing还可以更加精简,因为上面使用的也是字符串默认的比较方式:
TreeSet<Student> stu = new TreeSet<>(comparator.thenComparing( s->s.name) );
还有比较规则对于空值的处理:
reeSet<Integer> set = new TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder()));
nullsFirst表示如果传入值为null,比较级优先。naturalOrder表示默认的比较(从小到大)
set.add(5); set.add(1); set.add(2); set.add(null); System.out.println(set);

也可以这样写
TreeSet<Student> stu = new TreeSet<>(Comparator.comparing(s->s.age));
总结:
Comparator是类外面手动定义的一个比较规则,Comparable是类内部自行定义的衣服比较规则。