今天看java.util.Comparator 这个接口,看到里面除了有个 int compare(T o1,T o2); 这个抽象方法外,还有 boolean equals(Object obj);这个抽象方法。 
    我看到的代码,都没有实现这个抽象方法,(包括自己写代码,也没有实现),程序也不报错,是否说明这个方法在实现这个接口的类的父类(Object)已经实现了? 
    假设是这样的话,那这个方法就不需要定义了,(因为接口都要由类实现,而所有的类都是Object的子类,那自然都继承了这个方法,当然可以重写。
    如果不是这样的话,那它的意义究竟是什么呢?
    可能说的不清楚,简单的说,既然Object类里有了的方法,为什么在接口里还要定义抽象方法?

解决方案 »

  1.   

    方便要求实现类中实现方法的复写,定义自己指定的toString(),equals(),hashcode()方法。
      

  2.   

         * Note that it is <i>always</i> safe <i>not</i> to override
         * <tt>Object.equals(Object)</tt>.  However, overriding this method may,
         * in some cases, improve performance by allowing programs to determine
         * that two distinct comparators impose the same order.
      

  3.   

    是不是实现Comparator 接口的类中本来就有equels方法,所以一般不用再去实现它了!
      

  4.   

    这是为了在你的代码中对这两个方法进行重写(当你需要这样做时)。
    比如我们在Hibernate中采用复合主键类时:
    我们的Person类:Person.java
    @Entity                                 
    @Table(name="peroson_table")               
    public class Person
    {
    /*指定使用复合主键类是Name*/
    @EmbeddedId                         
    @AttributeOverrides({                    
     @AttributeOverride(name="first",column=@Column(name="person_first")),
    @AttributeOverride(name="last",columen=@Column(name="person_last",length=20))
    })
    private Name name;
    //普通属性
    @Column(name="person_email")
    private String email;
    ...Name属性的set和get方法
    ...Email属性的set和get方法

    })
    //Person的Name属性就是一个复合类型的标识属性}那么在Name类中我们要实现java.io.Serializable接口并重写hashCod()和equals()方法:
    Name.java//修饰组件属性类
    @Embeddable
    Piblic class Name implements java.io.Serializable
    {
    Private String first;
    Private String last;
    //无参数的构造器
    Public name()
    {
    }
    //初始化全局属性的构造器
    Public Name(String first,String laset)
    {
    This.first=first;
    This.last=last;
    }
    ...first属性的set、get方法
    ...last属性的set、get方法
    //提供重写的equals方法
    Public boolean equals(Object obj)
    {
    If(this==obj)
    {
    Return true;
    }
    If(obj.getClass()==Name.class)
    {
    Name target = (Name)obj;
    If(target.getFirst().equals(first) && target.getLast().equals(last))
    {
    Return true;
    }
    }
    Return false;
    }
    //提供重写的hashCode方法
    Public int hashCode()
    {
    Return fist.hashCode()+last.hashCod()*17;
    }
    }
      

  5.   

    这些方法在Object类里都有,需要重写的话,可以直接重写,为什么还要定义?
      

  6.   

    我看过这段话,就是不是很明白。
    api5。0翻译的是这样的:注意,不 重写 Object.equals(Object) 方法总是 安全的。然而,在某些情况下,重写此方法可以允许程序确定两个不同的 Comparator 是否强行实现了相同的排序,从而提高性能。 为什么说不重写是安全的? 这是针对什么说的?
    重写怎么能提高性能?
      

  7.   

    你好,我回复到这里吧:
    1.Object类并没有实现Comparator接口。
    2.如果你在你的代码中使用compare方法,还是需要自己写的。
    3.能否把代码贴上来,以供仔细查看。
      

  8.   

    comparator用于排序中使用,如果不重写就使用JDK默认的排序方式,如果重写就使用自己定义的方式。例如,整数默认排序规则是正序排列,你有一个需求需要反序排列,那么重写comparator方法就能实现反序排列。
      

  9.   

    排序compare这个方法是肯定要重写的,我的问题是这个Comparator接口里还有一个 equals()方法,这个方法在Object类里有,那在这个Comparator接口里还要定义一次有什么用?
      

  10.   

    Comparable接口中的compare()这个比较方法要与equals()这个方法达成一致,也就是要满足(a.compare(b)&&a.equals(b))为真这个规则。因为默认的equals方法是以对象本身进行比较的,也就是默认情况下,a.equals(b)==true时,a与b一定是同一个对象。而我们一般自定义的比较只需要a与b之间的内容相同即相等,而此时不同时重写equals方法的话,会导致内容相同a.compare(b)为true,但a.equals(b)为false(因为它们是不同的两个对象,虽然内容相同)。这样就会与我们之前所说的规则相冲突了。所以会在Comparable这个接口中也同时定义equals()这个方法,就是要提醒程序员在重写compare方法的时候也要修改equals方法。
      

  11.   

    你好:
          首先,为什么说不重写equals总是安全的。因为java中很多Collection你在取值时,实际是通过hashCode()来实现的。如果你重写了object的equals方法,可能意味着原来不相等的两个值现在奇怪的相等了,或是两个原来相等的值现在相等了。由此可能造成你原来存进去的值现在没法取出来。
          再者,为什么Comparator也有一个equals方法。接口是并不继承Object类的。这个方法用来比较其他对象是否等于这个比较器。当指定的对象也是一个比较器,并且和这个Comparator执行相同的顺序时,该方法返回true.
    参考资料:http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
      

  12.   

    这个Comparable接口,只有一个compareTo()方法,里面没有其他方法。与我问的问题不一样。
      

  13.   

    回复howlaa:
     “再者,为什么Comparator也有一个equals方法。接口是并不继承Object类的。这个方法用来比较其他对象是否等于这个比较器。当指定的对象也是一个比较器,并且和这个Comparator执行相同的顺序时,该方法返回true.”
        实际上我的问题就在这,接口虽然不是继承Object类,但实现接口的类肯定是继承Object的,那么这个类就会有equals()方法了。如果需要重写,就重写;不需要,可以不用管。 所以我不知道到底这个接口里定义的这个equals()有什么用?或者说,明明是已经有了的方法,为什么还要重复定义?
      

  14.   

    上面资料里已经说了,接口里的equals方法是比较两个比较器是否相等的。而重写Object的equals方法是比较此对象与另一个OBJ是否相等的。
      

  15.   


    注意,不去重写Object的equals方法总是安全的。但是,重写这个方法也许,在某些情况下,(有助于)提高效率,——因为这就允许程序作出这样的判断:两个不同的Comparator实现导致的排序结果其实是相同的。(比如两个Comparator分别对同一个巨大的集合排序,你要想知道结果是不是相同,就可以通过两个 Comparator 的 equals 结果知道,而不用去比较两个巨大的结果集合了)接口里面写上这个方法,我猜就是为了能有一个合适的地方写下这段注释,提醒程序员注意到这种对Comparator实现重写equals的可能性。当然,根据Object类里的equals协议,如果重写equals那就是说hashCode也要同时重写,这个还是要遵守的。
      

  16.   

    Comparetor作为外部比较器。往往是在集合中排序时使用的。但是站在开发人员的需求角度来考虑的话,可能在应用中并不是所有的集合在使用这些对象的时候都要排序的。Object的equals作为原生的比较方法。可能在其他地方jdk的开发人员会调用到这个方法。因此他们希望尽可能的不去动他,但是又可能趋于需求的考虑不将此方法定义为final。所以jdk文档才会解释尽量避免重写equals。-----全属个人见解。