都说equals比较的是对象内容。那么我写一个TestBean类:
public TestBean{}
然后测试:
public class TestMain {
public static void main(String[] args) {
TestBean t1=new TestBean();
TestBean t2=new TestBean();
System.out.println(t1.equals(t2));
}
}
为什么t1与t2不相等呢?如果说equals方法内部首先是比较hashcode,那我重写掉hashcode:
public class TestBean {
@Override
public int hashCode() {
return 1;
}}
然后再执行测试类,还是返回false。
求人解答,谢谢!

解决方案 »

  1.   

    equals(): 
    它是用于进行两个对象的比较的,是对象内容的比较,当然也能用于进行对象参阅值的比较。什么是对象参阅值的比较?就是两个参阅变量的值得比较,我们 都知道参阅变量的值其实就是一个数字,这个数字可以看成是鉴别不同对象的代号。两个对象参阅值的比较,就是两个数字的比较,两个代号的比较。这种比较是默 认的对象比较方式,在Object这个对象中,这种方式就已经设计好了。所以你也不用自己来重写,浪费不必要的时间。对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求如下,这些要求是必须遵循的。否则,你就不该浪费时间: 
    对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。 
    反射性:x.equals(x)必须返回是“true”。 
    类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。 
    还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。 
    任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。 
    hashCode():
    这 个函数返回的就是一个用来进行赫希操作的整型代号,请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的收集对象中的位置。这些对象是HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须自己设计,用来协助HashMap, Hashtable, HashSet,等等对自己所收集的大量对象进行搜寻和定位。这些收集对象究竟如何工作的,想象每个元对象hashCode是一个箱子的 编码,按照编码,每个元对象就是根据hashCode()提供的代号归入相应的箱子里。所有的箱子加起来就是一个HashSet,HashMap,或 Hashtable对象,我们需要寻找一个元对象时,先看它的代码,就是hashCode()返回的整型值,这样我们找到它所在的箱子,然后在箱子里,每 个元对象都拿出来一个个和我们要找的对象进行对比,如果两个对象的内容相等,我们的搜寻也就结束。这种操作需要两个重要的信息,一是对象的 hashCode(),还有一个是对象内容对比的结果。hashCode()的返回值和equals()的关系如下:如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。 
    如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。 为什么这两个规则是这样的,原因其实很简单,拿HashSet来说吧,HashSet可以拥有一个或更多的箱子,在同一个箱子中可以有一个 或更多的独特元对象(HashSet所容纳的必须是独特的元对象)。这个例子说明一个元对象可以和其他不同的元对象拥有相同的hashCode。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。
      

  2.   

    仅覆盖hashCode方法是不行的,比较晚hashCode方法后还是要进一步执行equals方法比较对象是否相等。因此你要覆盖Object类上的那个默认的equals方法实现。
    Object类上的equals方法比较的是两变量引用的对象是否是同一个对象。
      

  3.   

    楼主搞混了。Object 的equals方法比较的是地址。
    所以你的两个TestBean 对象,equals一下当然返回false。
    String类的equals方法比较内容,因为里面是重写了equals方法了。默认都是比较的地址。
      

  4.   

    首先区分equals和==, 对于对象类型的==操作,比较的是两个对象的引用地址;
    对于equals方法,若没有重写Object的equals方法, 就会调用Object的equals方法,而Object的equals方法用的是==操作来比较两个对象,也即和t1==t2是一样的;并不是你说的equals方法内部首先是比较hashcode;t1和t2是两个不同的对象,根据上面你就知道了System.out.println(t1.equals(t2));也即和System.out.println(t1.==t2);结果是一样的;所以呢,你加上下面的code到TestBean中,就会出现你要的结果了:        @Override
    public boolean equals(Object obj) {
    return obj == null ? false : getClass().equals(obj.getClass());
    }
      

  5.   

    我知道替换掉equals方法可以使两个对象相等。我只是想知道java在equals方法中做了什么处理?我看源码就是在里面做==判断。可是这样子除String之外的Object类的equals和==有什么区别?难道两者都是一样的,都是比较内存地址?
      

  6.   

    楼主 好像钻牛角尖了哦。== 用来比较2个对象的地址
    Object类的equals方法 默认实现恰好就是 使用== 来比较对象的地址.
    两者的比较效果当然是一样的。
      

  7.   

    重写equals方法。如果要装到容器中去也重写一下hashcode方法。至于你方法里要如何判断你的对象是否相等就看你的心情了。
      

  8.   

    LZ概念有点不清
    equals是比较对象的内容,是针对String而言的,因为很多人比较String的时候,容易犯==比较的错误实际上equals是Object的一个方法,任何子类都可以重写这个方法,来根据实际需求实现equals达到用户想比较的目的,如果一个类不重写equals方法,那么就会默认的调用父类的equals方法,而父类的equals方法就是简单的返回==的比较结果,所以是不能满足用户需求的。
      

  9.   

    你都看了Object类的equals方法是用==来处理比较两个对象,难道有区别吗?至于Object类的equals和==有什么区别?
    可以理解为Object类的equals你可以Override,==你没办法改(当然你也可以修改JVM来实现);
    JVM运行程序时遇到==,就会去判断对象的指针地址,不管是否重写了Object类的equals方法和hashCode方法;
    至于Object类的equals方法怎么重写,API写的很清楚,你可以按API的规则来重写实现,也可以不按API的规则来实现,简单说就是想让它怎样就怎样;但你如果不重写,Object类是用==来实现的;