黑马程序员技术交流社区

标题: 有关JAVA equals方法的疑问,大家来帮我看看啊 [打印本页]

作者: 丑男先生。    时间: 2013-12-14 16:38
标题: 有关JAVA equals方法的疑问,大家来帮我看看啊
//此处Public类的名称必须为Hello,用户不可修改。

public class Hello {

    private int size;

    private String name;

   

    Hello(String name,int size)

    {

        this.name=name;

        this.size=size;

    }

   

    public static void main(String[] args) {

        //System.out.println("Hello Fenby!");

        Hello helloKitty = new Hello("Kitty",3);

    Hello helloWideWorld = new Hello("World",1000);

        Hello helloAroundWorld = new Hello("World",1000);

if(helloKitty.equals(helloWideWorld))

        {

          System.out.println("helloKitty and helloWideWorld have the same meaning");   

        }

        else System.out.println("helloKitty and helloWideWorld don't have the same meaning");

      

        if(helloAroundWorld.equals(helloWideWorld))

        {

          System.out.println("helloAroundWorld and helloWideWorld have the same meaning");   

        }

        else System.out.println("helloAroundWorld and helloWideWorld don't have the same meaning");

   }

}

Java 对象的行为和方法一章的最后一节变量的比较,讲到equals方法:使用equals()来判断两个对象是否在意义上相等。课后练习中用equals对两个没有内容的对象进行判断,返回值是false。我就借鉴视频中的例子自己写了一个,可是helloAroundWorld和helloWideWorld用equals比较还是返回false。这里很疑惑。

大家看一看。为什么会这样呢?

作者: 回音    时间: 2013-12-14 17:01
本帖最后由 回音 于 2013-12-14 17:07 编辑

需要重写equals方法,代码中请加上:
public String getName ()
{
     return name;
}
public int getSize()
{
     return size;
}

@Override
public boolean equals(Object obj)
{
    if( ! (obj instanceof Hello) )
          return false;
    Hello h = (Hello) obj;
    return this.name.equals(h.getName()) && this.size == h.getSize();
}


因为Hello类继承自Object类,重写equals方法后Hello类中的equals方法就是比较Hello对象是否相等了。否则就会调用Object类中的equals方法,但那是比较对象引用是否相等的,这时就不相等了。

作者: 末末    时间: 2013-12-14 17:05
equals比较的是对象的内存地址,这个是两个对象,怎么可能相等呢,而String类里的equals覆写了object里的equsla方法,但是比较的是内容是否相等而不是内存地址,你这里用的是object里的equals方法所以比较的是内存地址,你这是两个不同的对象所以是false
作者: 翼展哈哈    时间: 2013-12-14 17:16
楼主您好,
查阅java api文档中的Object类中的equals方法可知:
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
        很明显,楼主代码中的两个引用helloAroundWorld和helloWideWorld并不是指向同一个对象,所以它们比较返回的结果是false!这是对楼主疑惑的解释。
        另外,equals方法的实现原理是什么呢?首先会比较两个对象的hashcode值是否一样。每产生一个对象就会产生一个该对象的hashcode值来标识这个对象,也就是说该对象区别于其他对象的其中一点就是hashCode值。楼主代码中的helloAroundWorld指向的对象实体和helloWideWorld指向的对象实体虽然属性及其内容是相同的,但是它们的hashcode值并不是相同的,所以调用equals返回的值就是false。至于hashCode值的产生原理,可以看老师的视频或者在网上寻找相关资料。
希望楼主可以理解,有什么不对的,欢迎批评指正!
        

作者: 谢文斌    时间: 2013-12-14 17:20
本帖最后由 谢文斌 于 2013-12-14 17:23 编辑
  1. 参考API:
  2. equals
  3. public boolean equals(Object obj)
  4.     指示其他某个对象是否与此对象“相等”。
  5.     equals 方法在非空对象引用上实现相等关系:

  6.         自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
  7.         对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
  8.         传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
  9.         一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
  10.         对于任何非空引用值 x,x.equals(null) 都应返回 false。

  11.     Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

  12.     注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

  13.     参数:
  14.         obj - 要与之比较的引用对象。
  15.     返回:
  16.         如果此对象与 obj 参数相同,则返回 true;否则返回 false。
  17.     另请参见:
  18.         hashCode(), Hashtable
复制代码

也就是说,你的两个对象满足自反性、对称性、传递性、一致性或者变量引用同一个对象时,且equals没有被重写,才会是true。其他情况,两个对象比较结果就会是false。




作者: 笑脸不在    时间: 2013-12-14 17:31
本帖最后由 笑脸不在 于 2013-12-14 17:35 编辑

说明:楼主题中所使用的equals是子类Hello继承父类Object中的equals函数。                                                                                                                     1、详解父类中的equals函数;      Object类中的equals()方法的API说明:
      对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)
     也就是说Object类中的equals方法的返回值==比较运算符的结果是一致的,他们比较的都是地址值;

2、 Hello helloWideWorld = new Hello("World",1000);
      Hello  helAroundWorld  = new Hello("World",1000);
       这里的 helloWideWorld 和 helloAroundWorld 都指向了Hello类对象,代表的是两个Hello类对象的内存地址值,所以helloWideWorld.equals(hellAroundWorld )的值是false。(显然的啦:两个对象的内存地址值是不同的~)
3、解决方法:
      在Hello类中定义自己的equals方法,复写掉Object类中的equals方法就好了,这样子类调用的时候就会调用子类的equals方法了:代码如下
          Boolean equals (Hello H)
            {
               return (this.size==h.name&&this.name=h.name);
            }




作者: 还记得梦想吗    时间: 2013-12-14 17:45
楼主代码谢得跟绕口令一样。。。简洁,易懂,注释。。。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2