自然排序:将需要排序的bean实现comparable接口,重写compareTo方法。
选择器排序:需要排序的bean不需要实现接口,将bean所在的数组或者集合中,指定使用的比较器实现Comparator接口,定义compare方法指定排序规则。
两种排序都是重写用来比较的方法,区别在于自然排序的compareTo方法只有一个参数。比较器的compareTo方法有两个参数。
Comparable接口:
Comparator接口:
都是返回一个int类型的值,自然排序中,大于比较值(方法中的参数)返回1,等于返回0,小于返回-1。顺序排序中,第一个参数大于第二个参数返回1,等于返回0,小于返回-1。
// 员工实现Comparable接口进行排序
public class Employee implements Comparable<Employee> {
private Long id;
private String name;
private String sex;
private Long salary;
@Override
public int compareTo(Employee o) {
// 对员工的薪水进行排序,如果薪水相同根据员工id排序
int result = Long.compare(this.getSalary(), o.getSalary());
if (result == 0) {
int idResult = Long.compare( this.getId(),o.getId());
return idResult;
} else {
return result;
}
}
上述代码中,执行的是自然排序。a.compareTo(b),如果a>b返回正数,a<b返回负数,a=b返回0。注意实现接口时,带有指定的泛型,如果不指定泛型,重写compareTo方法时参数仍是Object对象,需要自己手动进行强制转换,因为Java是一种强类型语言。同样的原因,为什么不直接在Employee类中自己定义一个CompareTo方法呢?通过定义指定的接口去实现可以在编译期间明确知道可以使用compareTo方法去进行排序对比。这也是接口的设计法则之一,定义规范。compareTo方法和equals方法类似都是在做bean之间的比较,但是a.equal(null)返回false,a.compareTo(null),会提示空指针。
根据员工的薪资排序,薪资相同,根据员工的id排序
降序:根据薪资降序,薪资相同根据员工id降序
@Override
public int compareTo(Employee employee) {
// 根据薪资排序,相同根据员工id降序
int result = Long.compare(this.getSalary(), employee.getSalary());
if(result ==0){
int idResult = Long.compare(this.getId(), employee.getId());
return Math.negateExact(idResult);
}
return Math.negateExact(result);
}
使用比较器排序:
public class Demo {
public static void main(String[] args) { // 2018-09-26T19:55:01.209+08:00
Employee employee1 = new Employee(1L, "小明", "男", 500L);
Employee employee2 = new Employee(2L, "小王", "男", 800L);
Employee employee3 = new Employee(3L, "小李", "男", 800L);
Employee employee4 = new Employee(4L, "小胖", "男", 600L);
Employee employee5 = new Employee(5L, "小帅", "男", 700L);
ArrayList<Employee> employees = Lists.newArrayList(employee1, employee2, employee3, employee4, employee5);
EmployeeSort employeeSort = new EmployeeSort();
Collections.sort(employees,employeeSort);
employees.stream().forEach(System.out::println);
}
public static class EmployeeSort implements Comparator<Employee> {
@Override
public int compare(Employee employee1, Employee employee2) {
// 顺序
int result = Long.compare(employee1.getSalary(), employee2.getSalary());
if (result == 0) {
int idResult = Long.compare(employee1.getId(), employee2.getId());
return idResult;
}
return result;
}
}
}
结果:
倒序结果与其类似,不再做演示。