比较Java子类

时间:2012-05-23 17:32:28

标签: java

我的应用可以比较同一抽象父类的任何两个子类的实例。我希望他们比较如下:

  1. 如果它们是不同的子类,则父类应进行比较。
  2. 如果它们是同一个子类,则子类应进行比较。
  3. 这些类将通过TreeMap进行比较,因此我可以选择使用Comparator,还是实现Comparable(或两者兼而有之?)。

    我可以想到几种方法来做到这一点,但它们都有点混乱且容易出错。有优雅的解决方案吗?

    提前致谢...

5 个答案:

答案 0 :(得分:2)

你可以尝试

// Parent:
@Override
public final int compareTo(Parent other)
{
  if (getClass() == other.getClasss()) {
    // same type -> pass it to subclass implementation
    return this.subCompare(other)
  }

  // different type -> do the comparison here based on Parent's logic
  // ...
}

protected int subCompare(Parent other)
{
  // this should not be called directly
  return 0; // could throw an exception here too
}

// Derived1:
@Override
protected int subCompare(Parent other)
{
  // this method is only called from Parent
  Derived1 other1 = (Derived1) other;
  // do the comparison based on Derived1's logic
}

与其他派生类类似

答案 1 :(得分:0)

这不是你问题的直接答案,但是:
我相信你所做的是容易出错和有问题的 compareTo方法强加的等式测试通常应返回与equals方法相同的结果。即compareTo方法强加的排序equals一致。
如果违反此合同,您可能会遇到排序集合(您正在使用)的问题 我为什么这么说:
在某些情况下,您希望将比较委托给父类的事实向我表明您已在子类中添加了值组件。
如果你这样做,那么就无法保留equals合同,你可能会遇到排序容器的问题(见上文)

答案 2 :(得分:0)

无论哪种方式都会出错。您可以在子类中执行以下操作:

class Subclass1 ... {

public boolean equals(Object o) {
  if(o instanceof Subclass1) {
    return super.equals(o);
  }

  ... compare subclasses
}

}

答案 3 :(得分:0)

班级层次结构是否应该可扩展? =>如果它不可扩展(或很少会被扩展),您可以实现一个Comperator,以便所有比较代码都在一个地方。

订购物品的方法有多种? =>如果是这样,那么你将不得不为每个订单使用一个comperator。

从三种情况调用

compareTo(other)(或compare(o1, o2)):

  1. this instanceof other.class(即o1 instanceof o2.class):
    • this.class应该比较thiso2,因为它比other.class有更多的信息;
  2. other instanceof this.class(即o2 instanceof o1.class):
    • other.class应该比较otherthis,而this.class.compareTo应该翻转结果并将其返回。
  3. 存在第一个共同的祖先P,使this instanceof P&& other instanceof P
    • P应比较thisother:递归调用super.compareTo(other)并返回结果。

答案 4 :(得分:0)

这就是我现在正在做的事情。我认为这样会很优雅:

public abstract class ParentClass implements Comparable<ParentClass> {
    // compareTo(ParentClass) is implicitly abstract
}


public class SubClass1 extends ParentClass /* Comparable<> is implicitly implemented */ {
    @Override
    public int compareTo(ParentClass another) {
        SubClass1 subAnother = (SubClass1) another;
        return /* result of sub-class comparison */;
    }
}


public class MyComparator implements Comparator<ParentClass> {
    @Override
    public int compare(ParentClass lhs, ParentClass rhs) {

        // Are lhs and rhs instances of the same sub-class?
        if(!lhs.getClass().equals(rhs.getClass()))
            // They are different. Use parent class comparison.
            return /* result of parent class comparison */;

        // They are the same. Use sub-class comparison.
        return lhs.compareTo(rhs);
    }
}

然后我只是将MyComparator的实例传递给TreeMap。它处理不同的子类比较,或者如果它们是相同的,则将比较传递给子类。

我不喜欢的是SubClass1.compareTo()如果ClassCastException是另一个子类的实例,则会抛出another。但是,只要我确保仅通过MyComparator比较子类,我就不必担心这一点。