【问题标题】:Why is equals not mandatory to implement in java.util.Comparator?为什么不强制在 java.util.Comparator 中实现 equals?
【发布时间】:2012-08-01 11:11:51
【问题描述】:

在 Javadoc 以及代码本身中,Comparator 接口定义:

 int compare(T o1, T o2);
 boolean equals(Object obj);

但是这不会给编译带来任何问题:

 Comparator a = new Comparator() {      
     @Override public int compare(Object o1, Object o2) {
        //..
     }
 };

但这确实:

 Comparator a = new Comparator() {      
     @Override public boolean equals(Object comparator) {
        //..
     }
 };

接口是如何实现不覆盖方法的?

【问题讨论】:

    标签: java interface comparator


    【解决方案1】:

    首先JavaDocs explain明确表示你应该实现这个方法:

    此外,只有当指定的对象也是一个比较器并且它强制执行与此比较器相同的排序时,此方法才能返回 true。因此,comp1.equals(comp2) 意味着 sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) 对于每个对象引用 o1o2

    但后来:

    请注意,不要覆盖Object.equals(Object) 总是安全的。

    怎么可能不覆盖equals(),即使它是接口的一部分?因为这个方法已经在 J​​ava 中为每个对象实现了(in Object class)。

    界面中的声明只是通过添加额外的 JavaDoc 解释来强调equals() 相对于Comparator 的重要性。

    顺便说一句,如果您的比较器是无状态的,您应该只有一个实例 - 在这种情况下,默认的 equal() 实现就可以了。

    【讨论】:

    • 我已经阅读了第二部分,但我的意思是,一个接口是否也像普通的 newable 实例一样扩展对象?或者你的意思是接口知道任何对象中已经实现了哪些方法,所以它不会强制它们?
    • @user1352530 实际上也不是。接口不知道Object。但是当你实现一个接口时,你总是直接或间接地继承自Object。这意味着你已经继承了equals() 和其他人,所以编译器没有抱怨。另一方面请注意,当您拥有任何接口的实例时,您仍然可以在其上调用任何Object 方法,而不仅仅是该特定接口的方法。
    【解决方案2】:

    因为每个对象都已经实现了 equals()。

    实际上,在 Comparator 接口定义中再次指定 equals() 只是提供了一个机会来记录合同及其与 compareTo() 的关系。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 2015-04-14
      相关资源
      最近更新 更多