java - 如何在Java中保持原始排序不变的情况下基于比较器执行排序

标签 java sorting collections comparator comparable

我一直在研究 Comparable 与 Comparator 接口(interface)的实现示例。

但是,我在它的实现过程中卡在了某个点:

假设,我有一个简单的类: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);
   }

}

但是,比方说,我必须先根据员工姓名进行排序,然后如果两位员工的姓名相同,我必须根据他们的薪水对他们进行排序。

所以,我编写了一个自定义比较器来根据薪水进行排序,如下所示

public class SalaryComparator implements Comparator<Employee> {

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

}

但是,当我运行我的测试类以首先根据姓名排序,然后根据薪水排序时,输出并不像预期的那样。

Collections.sort(employeeList, new SalaryComparator());

输入顺序:

Name : Kumar, Salary : 40
Name : Sanket, Salary : 10
Name : Kumar, Salary : 20

预期输出:

Name : Kumar, Salary : 20
Name : Kumar, Salary : 40
Name : Sanket, Salary : 10

实际输出:

Name : Sanket, Salary : 10 // incorrect order
Name : Kumar, Salary : 20
Name : Kumar, Salary : 40

最佳答案

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

例如,假设您的 Employees 的默认排序是按薪水升序排列。现在假设您要按薪水降序对它们进行排序。

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

Collections.sort(employees, new SalaryDescendingComparator());

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

作为doc状态:

Sorts the specified list according to the order induced by the specified comparator.

因为 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);
   }

}

关于java - 如何在Java中保持原始排序不变的情况下基于比较器执行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22607013/

相关文章:

java - 根据 Java 中传递的参数定义数据类型

java - 芬奇机器人编程

java - 按 int(权重)、字符串(名称)或 toString() 对 .txt 列表进行排序

algorithm - 在多张发票上分配一笔款项

java - 数组和数组列表之间的存储机制?

java - 是否完全使用 Adob​​e CQ5 (AEM) 编程进行开发?

java - Weld/CDI 的最佳调试技巧是什么?

python - 如何在 Python 中使用 lambda 进行排序

java - 向 Vector 解释哈希码

java - 在 Java 中声明一个 LinkedList