如何基于Comparator执行排序,保持原始排序在Java中完整无缺

sgo*_*les 1 java sorting collections comparable comparator

我一直在浏览Comparable vs Comparator接口的实现示例.

但是,我一直坚持在它的实施中:

假设,我有一个简单的类:Employee,它具有基于员工姓名的默认排序机制.

public class Employee implements Comparable<Employee> {

   private int empSalary;
   private String empName;

   @Override
   public int compareTo(Employee e) {
        return this.empName.compareTo(e.empName);
   }

}
Run Code Online (Sandbox Code Playgroud)

但是,让我们说,我首先要根据员工姓名排序,然后如果两个员工有相同的名字,我就要根据他们的工资对他们进行排序.

所以,我写了一个自定义比较器,根据下面的工资进行排序

public class SalaryComparator implements Comparator<Employee> {

      @Override
      public int compare(Employee e1, Employee e2)  {
        return e1.empSalary - e2.empSalary;
      }

}
Run Code Online (Sandbox Code Playgroud)

但是,当我运行我的测试类时,首先根据名称进行排序,然后是第二个工资,输出不是预期的.

Collections.sort(employeeList, new SalaryComparator());
Run Code Online (Sandbox Code Playgroud)

输入订单:

Name : Kumar, Salary : 40
Name : Sanket, Salary : 10
Name : Kumar, Salary : 20
Run Code Online (Sandbox Code Playgroud)

预期产量:

Name : Kumar, Salary : 20
Name : Kumar, Salary : 40
Name : Sanket, Salary : 10
Run Code Online (Sandbox Code Playgroud)

实际产量:

Name : Sanket, Salary : 10 // incorrect order
Name : Kumar, Salary : 20
Name : Kumar, Salary : 40
Run Code Online (Sandbox Code Playgroud)

Ale*_* C. 6

这不是因为您的Employee类已经有一个默认排序,使用Collections.sort自定义比较器将引入一个新的排序层.

例如,假设您的默认排序Employees是按工资升序排列的.现在让我们假设你想按工资降序排序.

根据你的逻辑,这将如何表现?

Collections.sort(employees, new SalaryDescendingComparator());
Run Code Online (Sandbox Code Playgroud)

事实是,当您提供自定义比较器时Collections.sort,它将只使用这个,而不是您在Employee类中实现的排序机制.

正如文件所述:

根据指定比较器引发的顺序对指定列表进行排序.

因此,SalaryComparator只比较员工的工资,这就是为什么你得到这个输出.

如果你想先按姓名排序,然后按工资排序,你必须一次性排序,即:

public class Employee implements Comparable<Employee> {

   private int empSalary;
   private String empName;

   @Override
   public int compareTo(Employee e) {
       int cmp = this.empName.compareTo(e.empName);
       return cmp != 0 ? cmp : Integer.compare(empSalary, e.empSalary);
   }

}
Run Code Online (Sandbox Code Playgroud)