我一直在研究 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/