java 类库里的接口(如Comparator,定义了Object类已存在的方法,这有什么意义?
今天看java.util.Comparator 这个接口,看到里面除了有个 int compare(T o1,T o2); 这个抽象方法外,还有 boolean equals(Object obj);这个抽象方法。
我看到的代码,都没有实现这个抽象方法,(包括自己写代码,也没有实现),程序也不报错,是否说明这个方法在实现这个接口的类的父类(Object)已经实现了?
假设是这样的话,那这个方法就不需要定义了,(因为接口都要由类实现,而所有的类都是Object的子类,那自然都继承了这个方法,当然可以重写。
如果不是这样的话,那它的意义究竟是什么呢?
可能说的不清楚,简单的说,既然Object类里有了的方法,为什么在接口里还要定义抽象方法?
[解决办法]
方便要求实现类中实现方法的复写,定义自己指定的toString(),equals(),hashcode()方法。
[解决办法]
* 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.
[解决办法]
我猜这个定义这个方法的意义就在于让实现接口的程序员注意到上面这段注释。
[解决办法]
是不是实现Comparator 接口的类中本来就有equels方法,所以一般不用再去实现它了!
[解决办法]
这是为了在你的代码中对这两个方法进行重写(当你需要这样做时)。
比如我们在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;
}
}
[解决办法]
你好,我回复到这里吧:
1.Object类并没有实现Comparator接口。
2.如果你在你的代码中使用compare方法,还是需要自己写的。
3.能否把代码贴上来,以供仔细查看。
[解决办法]
comparator用于排序中使用,如果不重写就使用JDK默认的排序方式,如果重写就使用自己定义的方式。
例如,整数默认排序规则是正序排列,你有一个需求需要反序排列,那么重写comparator方法就能实现反序排列。
[解决办法]
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方法。
[解决办法]
提醒你注意重写方法,我想到的就是这个了
[解决办法]
你好:
首先,为什么说不重写equals总是安全的。因为java中很多Collection你在取值时,实际是通过hashCode()来实现的。如果你重写了object的equals方法,可能意味着原来不相等的两个值现在奇怪的相等了,或是两个原来相等的值现在相等了。由此可能造成你原来存进去的值现在没法取出来。
再者,为什么Comparator也有一个equals方法。接口是并不继承Object类的。这个方法用来比较其他对象是否等于这个比较器。当指定的对象也是一个比较器,并且和这个Comparator执行相同的顺序时,该方法返回true.
参考资料:http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
[解决办法]
上面资料里已经说了,接口里的equals方法是比较两个比较器是否相等的。而重写Object的equals方法是比较此对象与另一个OBJ是否相等的。
[解决办法]
注意,不去重写Object的equals方法总是安全的。
但是,重写这个方法也许,在某些情况下,(有助于)提高效率,——因为这就允许程序作出这样的判断:两个不同的Comparator实现导致的排序结果其实是相同的。
(比如两个Comparator分别对同一个巨大的集合排序,你要想知道结果是不是相同,就可以通过两个 Comparator 的 equals 结果知道,而不用去比较两个巨大的结果集合了)
接口里面写上这个方法,我猜就是为了能有一个合适的地方写下这段注释,提醒程序员注意到这种对Comparator实现重写equals的可能性。
当然,根据Object类里的equals协议,如果重写equals那就是说hashCode也要同时重写,这个还是要遵守的。
[解决办法]
是啊,只是猜测……
[解决办法]
Comparetor作为外部比较器。往往是在集合中排序时使用的。但是站在开发人员的需求角度来考虑的话,可能在应用中并不是所有的集合在使用这些对象的时候都要排序的。Object的equals作为原生的比较方法。可能在其他地方jdk的开发人员会调用到这个方法。因此他们希望尽可能的不去动他,但是又可能趋于需求的考虑不将此方法定义为final。所以jdk文档才会解释尽量避免重写equals。-----全属个人见解。