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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王震阳老师 金牌黑马   /  2012-10-12 12:35  /  1967 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

提示: 该帖被管理员或版主屏蔽
签名被屏蔽

6 个回复

倒序浏览
生成hash码,内存泄露。
当一个对象被存储进HashSet集合中以后,就不能修改这个对象中那些参与计算哈希值的字段了,否则,对象修改以后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果(字段值一改变,hashcode就会改变,相应的引用地址也会改变,导致以前的引用作废),这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
在想set类型的集合中存数据是 重写hashCode方法可以确保数据的唯一性
因为在set类型集合中存数据是元素会调用其hashCode方法来得到一个hash值来判断hash表中是否有相等的hash值如果有相等的就会继续调用equals方法来判断是否为同一对象
若是同一对象就不会将这个元素存储到集合中 并且hashCode方法和equals方法都是集合底层自动调用的
Set中对于判断元素是否存在 以及删除操作等 依赖的是元素的hashcode和equas方法

评分

参与人数 1技术分 +1 收起 理由
谭立文 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
按哈希值存储结构的集合,例如HashMap,HashSet。保证元素唯一性方法就是判断HashCode值。若hashCode值一样,会再调用equals方法判断值是否相同,如果不同,就会在同一个地址值下顺延,如果相同就不存了。有时候我们开发时会需要人为判断是否是同一个元素,这时就需要重写HashCode方法。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
楼上的3位都是正解
回复 使用道具 举报
hashcode方法返回该对象的哈希码值。保证元素的唯一性
支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable   提供的哈希表。  

hashCode的常规协定是:  
在   Java   应用程序执行期间,在同一对象上多次调用   hashCode   方法时,必须一致地返回相同的整数,前提是对象上   equals   比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。  
如果根据   equals(Object)   方法,两个对象是相等的,那么在两个对象中的每个对象上调用   hashCode   方法都必须生成相同的整数结果。  
以下情况不   是必需的:如果根据   equals(java.lang.Object)   方法,两个对象不相等,那么在两个对象中的任一对象上调用   hashCode   方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。  
实际上,由   Object   类定义的   hashCode   方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是   JavaTM   编程语言不需要这种实现技巧。)  
当equals方法被重写时,通常有必要重写   hashCode   方法,以维护   hashCode   方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
hashCode方法对于HashSet的作用是什么?
  要理解hashCode方法的作用,先要理解hash(也被翻译为哈希、散列)算法的功能:它能保证通过一个对象快速查找到另一个对象。hash算法的价值在于速度,它可以保证查询得到快速执行。当需要查询集合中某个元素时,hash算法可以直接根据该元素的值得到该元素保存在何处,从而可以让程序快速找到该元素。为了理解这个概念,可以先看数组(数组是所有能存储一组元素里最快的数据结构):数组可以包含多个元素,每个元素也有索引,如果需要访问某个数组元素,只需提供该元素的索引,该索引即指出了该元素在数组内存区里的存储位置。
  表面上看起来HashSet集合里的元素都没有索引,实际上当程序向HashSet集合中添加元素时,HashSet会根据该元素的hashCode值来决定它的存储位置——也就是说每个元素的hashCode就是它的“索引”。
  为什么不直接使用数组,还需要使用HashSet呢?因为数组元素的索引是连续,而且数组的长度是固定的,无法自由增加数组的长度。而HashSet就不一样了,HashSet采用每个元素的hashCode作为其索引,从而可以自由增加HashSet的长度,并可以根据元素的hashCode值来访问元素。因此,当从HashSet中访问元素时,HashSet先计算该元素的hashCode值(也就是调用该对象的hashCode()方法的返回值),然后直接到该hashCode对应的位置去取出该元素——这就是HashSet速度很快的原因。
二、如何重写hashCode方法?
重写hashCode()方法基本规则:
q 当两个对象通过equals方法比较返回true时,这两个对象的hashCode应该相等。
q 对象中用作equals比较标准的属性,都应该用来计算hashCode值。
重写hashCode()的方式:
(1)为对象内每个有意义的属性f(即每个用作equals()比较标准的属性)计算出一个int类型的hashCode值。计算方法如下表所示:

属性类型
计算方式
boolean
hashCode = (f ? 0 : 1);
整数类型(byte、short、char、int)
hashCode = (int)f;
long
hashCode = (int)(f ^ (f >>>32));
float
hashCode = Float.floatToIntBits(f);
double
long l = Double.doubleToLongBits(f);
hashCode = (int)(l ^ (l >>> 32));
普通引用类型
hashCode = f.hashCode();
(2)使用第1步计算出来多个hashCode组合计算出一个hashCode值返回。例如如下代码:
return f1.hashCode() + (int)f2;
如果为了避免直接相加产生偶然相等(两个对象的f1、f2属性并不相等,但他们的和恰好相等),可以通过为各属性乘以任意一个质数后再相加。例如如下代码:
return f1.hashCode() * 17+ (int)f2 * 13;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马