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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马薛有义 黑马帝   /  2011-7-18 09:18  /  2170 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

重写equals()方法一定要重写hashcode()方法吗?这两个方法有什么联系?

4 个回复

倒序浏览
黑马网友  发表于 2011-7-18 09:30:10
沙发
你说的是HashSet把。HashSet里面的值是不能重复的,所以在重写equals方法的时候,要重写hashcode,如果他们equals方法相同,则返回的hashcode值也应该相同。因为HashSet是根据hashcode排放集合里的元素的。如果equals不同,而hashcode返回相同。则在取出数据的时候。很难说取出的哪个值。
回复 使用道具 举报
黑马网友  发表于 2011-7-18 09:32:04
藤椅
我的理解:hashcode()的值是有关的是内存映射,一般都是按所定义的类的不同来决定这个值,也就决定了内存中类的存放地址,也就是说一个类的实例对象是放在一片区域之中的。当然,具体的hashcode值(没有重写情况下)是具体参数有关。所以如果两个对象相同的话,肯定hashcode值也相同。两个对象比较的时候,如果直接调用equals方法,如果对象过多会影响比较速度和效率,所以先比较hashcod值,如果这个值相同,在调用equals方法。也就是说一般,重写equals方法,都要重写hashcode方法。
整体来说:一个类的实例对象,如果equals方法是true,则hashcode值一定相同。但是,hashcode值相同,equals不一定是true
回复 使用道具 举报
黑马网友  发表于 2011-7-18 09:44:26
板凳
两者没有太大的联系,我记得在对象存储进HashSet集合里面的时候,equals方法和hashCode方法都要进行重写。因为HashSet集合的底层存储结构是哈希表。

每个对象都从具备equals方法,作用是判断两个对象的内容是否相同,当equals方法进行不了对象内容的判断的时候,我们就要对其进行重写。以达到我们的应用要求。

但,同时并不一样要重写hashCode方法。

因为每个对象都继承了Object类的hashCode方法。这是一个native(本地)方法,用C++编写,JAVA调用的时候看不到源代码。其实这是一个哈希算法,我们可以理解返回的是一个对象存储的物理地址。一般情况下equals方法比较相同,hashCode方法比较也相同,但是hashCode方法比较相同,equals方法比较不一定相同。
回复 使用道具 举报
黑马网友  发表于 2011-7-18 10:11:08
报纸
HashCode()方法只是在HashSet集合中才能体现出他的作用,HashSet集合用的是Hash算法来快速查找对象,所以shCode()就好比集合元素的索引

其实关于重写equals方法比较普遍,但是在用到HashSet集合的时候就会需要重写这个方法的时候还需要重写hashCode()方法,
简单的说HashSet存储一个元素的时候,HashSet会调用HashCode()方法来得到该对象的HashCode()返回值,再根据这个返回值来决定这个对象存储在HashSet的位置,如果两个元素通过equals比较返回true,但他们的hashCode()返回值不相等,HashSet会把他们存储在不同的位置,也就可以添加成功

[color=Red]也就是说HashSet判断两个集合相等的标准是两个对象通过equals方法比较相等,并且两个对象的HashCode()返回值也相等[/color]
例如如下例子,一个重写HashCode()一个重写equals  最后一个重写两个方法[code=java]package cn.itcast.zhanjc;


import java.util.*;
/**
*
*/

//类A的equals方法总是返回true,但没有重写其hashCode()方法
class A
{
        public boolean equals(Object obj)
        {
                return true;
        }
}
//类B的hashCode()方法总是返回1,但没有重写其equals()方法
class B
{
        public int hashCode()
        {
                return 1;
        }
}
//类C的hashCode()方法总是返回2,但没有重写其equals()方法
class C
{
        public int hashCode()
        {
                return 2;
        }
        public boolean equals(Object obj)
        {
                return true;
        }
}
public class HashCode
{
        public static void main(String[] args)
        {
                HashSet books = new HashSet();
                //分别向books集合中添加2个A对象,2个B对象,2个C对象
                books.add(new A());
                books.add(new A());
                books.add(new B());
                books.add(new B());
                books.add(new C());
                books.add(new C());
                System.out.println(books);
        }
}[/code]结果[code=java][cn.itcast.zhanjc.B@1, cn.itcast.zhanjc.B@1, cn.itcast.zhanjc.C@2, cn.itcast.zhanjc.A@1fb8ee3, cn.itcast.zhanjc.A@c17164][/code]------------------------------------------------------------------------------------
从上可以看到当重写一个equals或者hashCode()时候集合能添加通过equals方法返回true的元素、并且虽然HashCode()方法返回true但是HashSet依然把他们当成两个对象、这样就与Set集合规则不符合
所以在重写HashCode()方法的基本原则上要注意:
1、当两个对象通过equals方法返回true时,这两个对象的HashCode()也应该相等
2、对象中用作equals比较标准的属性都应该用来计算HashCode的值

评分

参与人数 1技术分 +3 收起 理由
admin + 3 不错,回答得很全面!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马