【问题标题】:CompareTo Overide SortCompareTo 覆盖排序
【发布时间】:2012-06-17 01:49:17
【问题描述】:

我在覆盖 compareTo 方法时遇到问题。该程序模拟了不同的员工类型,我完美地按员工类型排序,但不能让它按总工资进行二次排序。一旦它按类名/员工类型排序,它就需要按 GrossPay 排序,我可以通过辅助方法获得。下面是代码:

  public int compareTo(Object o) {

    Employee other = (Employee) o;

    if(other instanceof Salaried)
        return -1;

    else if(other instanceof Daily)
         return 1; 

    else
        return 0;
}

我正在将 Collection.sort() 与雇员的数组列表一起使用。当我打印出来时,我会得到一个按员工类型排序的很好的列表,但它应该按 GrossPay 排序。

【问题讨论】:

标签: java compareto


【解决方案1】:

compareTo必须返回与总订单一致的结果。否则无法以任何方式保证排序结果。总订单意味着如果A<B,那么B>A,如果A==B,那么B==A。也就是说,你可以切换thisother,结果是一致的。即使对于员工类型,您提供的代码也不会这样做。

如果compareTo 与总顺序不一致,sort 可能会产生错误的答案或永远不会终止。

尚不清楚您的系统是否有 3 种类型的员工或 2 种类型的员工。假设它是 2 种:受薪员工和日常员工。然后我们需要解决各种可能性:

this     other    result
------------------------
salaried salaried equal
daily    salaried <
salaried daily    >
daily    daily    equal

只有在我们确定 this 和 other 在员工类型上相等之后,我们才会采用次要排序键,即总工资。

所以编码的一种方法是:

// Assume this and o have type Daily or Salaried.
public int compareTo(Object o) {
  if (this instanceof Daily && o instanceof Salaried) return -1;
  if (this instanceof Salaried && o instanceof Daily) return +1;
  // The employee types must be equal, so make decision on pay.
  Employee e = (Employee)o;
  return grossPay() < e.grossPay() ? -1 :
         grossPay() > e.grossPay() ? +1 : 0;
}

我假设这是在 Employee 中实现的。

最后,使用Comparator 实现这种排序可能会更好。 compareTo 方法应保留用于“自然”排序顺序,例如用作主键的唯一 ID 号的数字顺序。这种排序标准似乎并不“自然”。

【讨论】:

    【解决方案2】:

    比较类型后可以比较grossPay。假设grossPay是一个数字。

    public int compareTo(Object o) {
    
        Employee other = (Employee) o;
        if(this instanceof Daily && other instanceof Salaried)
            return -1;
    
        else if(this instanceof Salaried && other instanceof Daily)
            return 1; 
    
        else
            return this.getGrossPay() - other.getGrossPay();
    }
    

    【讨论】:

    • 关闭,但是因为有溢出的可能,所以不应该使用整数减法来实现compareTo。如果getGrossPay() 已经返回Integer 值,您可以使用Integer.compareTo,但对于原语,请坚持使用&lt;&gt;。在 Java 7 中有静态方法Integer.compare(int, int)
    • 不幸的是,这不一定有效。如果 this 是受薪且 other 是受薪,这将返回 -1。如果交换两个操作数,它将再次返回-1。因此比较与总顺序不一致。排序可能会产生错误的答案或永远不会终止。
    • @TedHopp 感谢您的建议。我认为 GrossPay 的价值应该是正的。所以它不会溢出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    相关资源
    最近更新 更多