A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 田向向 高级黑马   /  2012-7-3 09:33  /  1605 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 田向向 于 2012-7-3 14:09 编辑

以我的理解复写equals()的时候是要复写hashcode()的,但是今天看到两篇博文,一篇介绍的是复写equals()的时候一定要复写hashcode(),而另一片却说当用到某些集合(HashSet、LinkedHashSet、HashMap、LinkedHashMap)的时候,一定要复写hashcode()方法,因为这些集合用到了哈希算法,哈希算法一定要用到hashcode(),而一般情况下不需要复写hashcode()方法,这两篇博文把我搞懵了,我本来基础就不好,谁能帮我解答一下,还有那篇博文上有代码我也没看懂,,谁能帮我解答一下,万分感谢!!!

public boolean equals(Object obj)
{  
       boolean result = false;  
       if (obj == null)
            {  
                   result = false;  
            }  
   
            if (this == obj)
            {  
                   result = true;  
            }  
   
            if (obj instanceof Student)
           {  
                   Student stu = (Student) obj;  
                   if (stu.getName().equals(this.name) && stu.getAge() == (this.age))
                   {  
                           result = true;  
                   }  
            }
             else
           {  
                   result = false;  
            }  
              return result;  
}

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

3 个回复

倒序浏览
关于你提到的代码
if (obj == null)
            {  
                   result = false;  
            }  
这个条件要求被比较的对象不能为空,即被比较的对象必须被初始化
if (this == obj)
            {  
                   result = true;  
            }  
这个条件是说如果被比较的对象在内存中的地址与比较对象相同则认为相等,显然嘛,内存地址相等就等于说是同一个对象
if (obj instanceof Student)
           {  
                   Student stu = (Student) obj;  
                   if (stu.getName().equals(this.name) && stu.getAge() == (this.age))
                   {  
                           result = true;  
                   }  
            }
这个条件就是说被比较的对象非空且内存地址也不等的时候,即两个不同的实例,则比较实例的属性,如果属性相等则也认为是同一个对象。

至于你问的覆写hashCode()方法,我的理解是这样的:
Object的原始的hashCode()方法中是将对象的内存地址值作为实例的哈希值,因此在使用Set的时候就一定要覆写hashCode()方法
原因是Set在add一个新对象的时候并不是将这个新对象与Set内的对象逐一通过equals()进行比较,而是比较新对象与Set内的对象的哈希值以区分新对象是否重复,因为Set中不允许存在重复元素嘛。用你程序中的例子比如我new了两个Student类的新对象
Student s1 = new Student("zhangsan",21);
Student s2 = new Student("zhangsan",21);
你先将s1添加入一个Set,之后添加s2,此时你肯定希望s2无法被添加,因为s2和s1是同一个人
如果你不覆写Student类的hashCode()方法,那么此时s2是可以被添加的,因为s2与s1的内存地址不同
那么,如果你覆写了hashCode(),并且在方法中使用学生的姓名和年龄来生成一个哈希值,那么这个时候s2就可以顺利的无法被添加,因为你通过覆写后的hashCode()给与了姓名和年龄都相同的两个不同实例相同的哈希值

点评

谢谢你啦,我是新手,有很多不懂的地方,希望以后可以多多帮助  发表于 2012-7-3 13:29

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1 赞一个!

查看全部评分

回复 使用道具 举报
这个你可以看看李刚的“疯狂java讲义”集合这一章,如果你要想往set集合里面加入相同的元素,就需要重写,hashcode()和equals()方法,因为Set集合就是判断两者是否相等,才往里面添加元素。
下面是你代码的意思

public boolean equals(Object obj)
{  
       boolean result = false;  
       if (obj == null)  //判断obj是否为空
            {  
                   result = false;  
            }  
   
            if (this == obj) // 判断调用对象是否是obj
            {  
                   result = true;  
            }  
   
            if (obj instanceof Student) //判断传入的obj是否是student类型
           {  
                   Student stu = (Student) obj;  //向下转型,也就是强制类型转换
                   if (stu.getName().equals(this.name) && stu.getAge() == (this.age))
                   {  
                           result = true;  
                   }  
            }
             else
           {  
                   result = false;  
            }  
              return result;  
}

点评

谢谢你啦,  发表于 2012-7-3 13:28

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
在每个重写了equals方法的类中,你必须也要重写hashCode方法。如果不这样做的话,就会导致该类无法与所有基于散列值(hash)的集合类结合在一起正常运行。

      hashCode()的返回值和equals()的关系如下:

      如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。

      如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马