【问题标题】:Java Comparable and InterfaceJava 可比和接口
【发布时间】:2018-10-28 01:24:04
【问题描述】:

假设您有 ClassA、ClassB、ClassC 和 interfaceA。

ClassA和ClassB实现interfaceA,classC包含一个List

现在假设我们将 ClassA 和 ClassB 中的一些值添加到 ClassC 列表中

如果 ClassA 实现与 ClassB 不同的可比较方法 CompareTo 会发生什么,我们调用 Collection.sort(list)

将应用哪个 CompareTo 对列表进行排序?或者我们必须在每个实现 interfaceA 的类中都有相同的 CompareTo 方法

【问题讨论】:

    标签: java


    【解决方案1】:

    Comparable 接口不是最好的方法。我建议使用传入 Collection 排序方法的 Comparator。

    【讨论】:

    • 这就是我的想法,所以我们可以对列表中的每个对象使用相同的排序算法
    【解决方案2】:

    我认为您无法运行此类代码。假设你有一个抽象类:

    public abstract class Number<T extends Number<T>> implements Comparable<T> {}
    

    以及扩展它的两个类:

    public class One extends Number<One> {
        @Override
        public int compareTo(One o) {
            return -1;
        }
    }
    
    public class Two extends Number<Two> {
        @Override
        public int compareTo(Two o) {
            return 0;
        }
    }
    

    然后执行下面的sn -p:

    List<Number> list = new ArrayList<>();
    list.add(new One());
    list.add(new Two());
    Collections.sort((List<Number>) list);
    

    会抛出 ClassCastException

    Exception in thread "main" java.lang.ClassCastException: comparable.One cannot be cast to comparable.Two
    

    一般来说,您的想法违反了 compareTo 方法的约定(参见 Joshua Bloch Effective Java,第 12 条):

    • 实施者必须确保所有 x 和 y 的 sgn(x.compareTo(y)) == -sgn(y.compareTo(x))。
    • 实现者还必须确保关系是可传递的:(x.compareTo(y) > 0 && y.compareTo(z) > 0) 意味着 x.compareTo(z) > 0。
    • 最后,实现者必须确保 x.compareTo(y) == 0 意味着 sgn(x.compareTo(z)) == sgn(y.compareTo(z)) ,对于所有 z 。
    • 强烈建议但不严格要求 (x.compareTo(y) == 0) == (x.equals(y))。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多