【问题标题】:How to implement comparator如何实现比较器
【发布时间】:2026-02-01 22:05:01
【问题描述】:

我得到了下面的代码作为家庭作业。我被要求为员工对象实现比较器。 compare 方法返回一个 int。但是,如果您比较它们,我在员工类中的所有方法都不会返回 int。谁能给我一些关于比较方法应该如何工作的指导?谢谢

import java.util.*;
import java.io.*;
public class EmployeeClient
{
//A Comparator for Employees
// Primary key   : Employee category - Salaried > Weekly > Daily
// Secondary key : Employee gross pay
private static class EmployeeComparator implements Comparator
{
  public int compare(Object one, Object two)
  {   
      Employee uno = (Employee) one;
      Employee dos = (Employee) two;

  }
}

public abstract class Employee {

private String idNumber;
private double payRate;

//Accessor: Return the id number of employee
public String getidNumber()
{
    return idNumber;
}

//Accessor: Return the payrate of the employee
public double getpayRate()
{
    return payRate;
}

public String toString()
{
    return getidNumber()+" "+getpayRate();
}

public abstract double grossPay();

}

【问题讨论】:

  • 员工类别没有方法/字段。然后,您可以根据比较工资值来比较员工总工资和回报 -1、0 或 1。
  • 比较器返回的是一个 int,以便可以在两个对象实例之间建立排序(小于、等于、大于)。在 cmets 中为 Comparator 提供的关键属性是 Employee 的哪些属性决定了排序关系? 您被告知先按员工类别排序,然后是总工资,但 Employee 没有“类别”属性,因此问题未完全指定。

标签: java


【解决方案1】:

我建议查看this link

自定义比较器的目标是获取两个对象并确定它们之间的关系。将其视为排序问题。假设我有两个装有红色和蓝色弹珠的袋子。如果我想根据蓝色弹珠来比较袋子,这就像问哪个袋子里的蓝色弹珠多/少一样。

比较函数的返回值决定了哪个对象的价值高于另一个。设ret 为比较两个对象后的值。

  • ret > 0 表示左侧对象的价值高于右侧
  • ret < 0 表示右侧对象的价值高于左侧
  • ret == 0 表示两个对象的值相同

希望这会有所帮助。

编辑:

如果您不允许或无法修改 Employee 类,请在您的第一组代码中的比较函数中进行比较。例如,如果你想比较两个整数 int aint b,你可以这样做:

a.compareTo(b)

Integer.compare(a, b)

  • 如果 a > b :任何一种方法都将返回一个大于 0 的值
  • 如果 a < b :任何一种方法都会返回一个小于 0 的值
  • 如果 a == b :任何一种方法都会返回 0

只需将这个想法应用到您的代码中

【讨论】:

  • 我打算使用 int 比较 =uno.compareTo(dos);并返回比较,但我的员工类没有 compareTo 方法,我认为我不能添加它。
  • @user1166061 这是一个完全可行的选择。这将要求您在 Employee 类中编写 compareTo() 函数。您需要考虑如何“订购”您的员工(即按 ID 号或按工资率)。还要想想身份证号码相同时会发生什么。
  • @user1166061 如果不允许在 Employee 中创建 compareTo() 函数,则可以在第一组代码中的 compare 函数中进行比较。只需使用 Employee 中定义的 get 函数来确定如何对员工进行排序
  • @Alex*s 这意味着Employee 类必须实现Comparable<Employee> 接口,这不是练习的目的,因此不是解决此问题的可行选项。
  • @user1166061 字符串和整数一样。 String 对象具有以相同方式工作的 compare() 和 compareTo()。结果与字符串的字典顺序有关。但正如 Luiggi 指出的那样,您的重点似乎应该放在薪水以及您的老师希望您如何操纵它来对员工进行排名。
【解决方案2】:

实际上,在比较时,您的 Employee 类中的所有字段都返回整数。

此外,每个 Employee 方法都会返回一个对象,该对象可以使用 compareTo() 进行比较以返回一个 int。

您的 Employee 类有两个字段:

String idNumber;
double payRate;

StringDouble(double 的对象形式)都有一个返回 int 的 compareTo() 方法。

所以...您的 EmployeeComparator.compare() 方法可以简单地返回:

one.getidNumber().compareTo(two.getidNumber());

以下是重写 Comparator 类的方法:

private static class EmployeeComparator implements Comparator<Employee>
{
  public int compare(Employee empOne, Employee empTwo)
  {   
      return empOne.getidNumber().compareTo(empTwo.getidNumber());
  }
}

上面的比较器严格根据员工编号进行比较。

但是...如何修改它以考虑其他字段应该很明显。

【讨论】:

    【解决方案3】:

    嗯,它总是取决于你想要排序的属性。对于像这样的通用实体,我建议使用它的内部 id。但是:Employee 类实际上设计得很糟糕。 getIdNumber() 应该返回 int 而不是 String。如果您可以重新设计课程,那就去做吧!如果不使用Integer.parseInt()解析字符串,那么你将有一个int进行比较。

    【讨论】:

    • 您关于 String 的观点不一定正确。员工 ID 可能恰好是数字,但您不会对其进行任何数字运算(很可能),因为该数字可能纯粹是作为员工查找的键而不是算术的。电话号码的类似讨论:*.com/questions/12331656/…
    • 你到底怎么知道Employee.idNumber的要求?哪里有人说它必须是一个数字?猜测设计在这里没有位置......它与编写比较器无关。
    • @chessbot 通常整数用于 id。有些情况下字符串很有用,这些情况就像您已经提到的更复杂的键,例如电话号码或 GUID。但是对于 90% 的用例,整数就可以了。由于该属性被命名为 id NUMBER,因此它的逻辑假设是它的数字......
    • 根据对属性名称或“90% 的时间发生了什么”的假设来批评他的设计似乎很荒谬。另外,这个问题与如何实现员工 ID 号无关。这是关于比较器的。我认为员工 ID 可以包含字母是完全合理的。
    • "但是,如果您比较它们,我在员工类中的所有方法都不会返回 int" 不,不是吗?我认为 OP 知道如何减去整数,但对要比较的内容感到困惑。在问题的背景下,我仍然认为我的回答是合法的-.-