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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wangqing 黑马帝   /  2011-11-16 13:22  /  2257 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wangqing 于 2011-11-27 13:35 编辑

当向hashSet中存储对象时,为什么要重写hashCode方法和equals方法?当向hashSet中存数据时,这两个方法是怎样被调用的?

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

5 个回复

正序浏览
这两个方法是在底层被调用的
回复 使用道具 举报
首先,这两个方法都来自于Object对象,根据API文档查看下原意。(1)public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。(2)public int hashCode() 返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表。
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,导致混淆,因此,就也需要重写hashcode。为了保证这种一致性,必须满足以下:

   (1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
    (2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false

如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等.
希望对您有所帮助!
回复 使用道具 举报
HashSet实现了Set接口。而且也应该知道Set集合中是不能包含重复元素的。
那么怎么判断要add的对象是否是重复的元素呢?
这时就要通过用hashCode()和equals()方法来判断。
而hashCode()是Object类的方法(equals()方法也是),所有类都间接或直接继承了Object类,因此需要重写hashCode()和equals()方法

如下一个示例:
HashSet hs = new HashSet();               
hs.add("001");
hs.add("002");
hs.add("001");//重复元素

参照以上示例说明原理:
当调用HashSet的add(Object a)时,
1.将a的hashCode值(直接说成hashCode值)与已有元素的hashCode值进行比较,如果不同则直接加进去,
2.如果hashCode值相同则接着调用equals方法比较,如果equals方法返回真则不加,返回true则加进去。
回复 使用道具 举报
向TreeSet中存入对象时,还需要复写hashCode方法和equals方法吗
回复 使用道具 举报
楼主需要明白几点:
1. hashSet 中不允许有重复的对象。
2. Java 通过调用对象的hashCode方法和equals方法判断两个对象是否相同。
3. 自定义类必须重写这两个方法不然机器可不知道怎么样算两个对象相同。

SO,向hashSet中加入对象时,机器需要拿新的对象做比对,看看是否已经重复了,所以会调用这两个方法。然后再决定是否将新对象添加进集合。
希望能帮到您。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

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