黑马程序员技术交流社区

标题: hashcode()的方法是在什么时候时需要用到? [打印本页]

作者: 蔡建荣    时间: 2012-7-24 22:26
标题: hashcode()的方法是在什么时候时需要用到?
我看了好多遍 我理解了毕老师说的前半句 当元素存在hashset的时候只是比较地址值 ,为避免重复  所以我们是需要 根据自定义元素自身的条件特点来判断唯一性,   这是什么意思?  能说简单点解释hashCode()方法的应用原理 和那句话吗?   谢谢。
作者: 乐峰    时间: 2012-7-24 22:41
Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
  所以,Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同

作者: 李菁    时间: 2012-7-24 23:10
Java中的集合分两类,List和Set。List中元素是有序的,可以重复;Set元素无序,不可重复。
判断两个元素是否重复。在集合中比较两个元素就要用hashCode。hashCode返回的就是根据对象的内存地址换算出的值,集合要添加新的元素时,先调用这个元素的hashCode方法,就能直接找到元素应该在的位置。
如果这个位置上没有元素,就可以直接存储在这个位置上,不用再进行任何比较。
如果这个位置上已经有元素了,就调用equals方法和新元素进行比较,相同就不存储,不相同就放到其他的地址
作者: 蔡建荣    时间: 2012-7-25 00:33
聂峰 发表于 2012-7-24 22:41
Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是 ...

虽然已经拿到分了  但还能不能回答我一下。  对象同 hashcode 同 我能理解 , hashcode相同 为什么对象不一定同?
作者: 蔡建荣    时间: 2012-7-25 00:41
聂峰 发表于 2012-7-24 22:41
Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是 ...

public int hashcode(){
return name.hashcode()+age*34
}

这个 return 中的+ age*34是为何?    虽然没分 就当是做好事吧! 麻烦了..
作者: 朱云坤    时间: 2012-7-25 03:50
蔡建荣 发表于 2012-7-25 00:33
虽然已经拿到分了  但还能不能回答我一下。  对象同 hashcode 同 我能理解 , hashcode相同 为什么对象不 ...

Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同
这个规则为什么是这样,拿HashSet来说吧,HashSet里可以有一个或者多个箱子,箱子里可以放入一个或者多个独特的元对象。说明,一个元对象可以和多个元对象拥有相同的hashCode,但这个元对象只能和拥有同样内容的元对象进行比较。所以两个对象的HashCode相同,它们可能并不相同。

作者: 朱云坤    时间: 2012-7-25 04:06
蔡建荣 发表于 2012-7-25 00:33
虽然已经拿到分了  但还能不能回答我一下。  对象同 hashcode 同 我能理解 , hashcode相同 为什么对象不 ...
  1. public int hashcode(){
  2. return name.hashcode()+age*34//其实就是覆盖Object类中的hashCode方法
  3.                                                   //来自己设计一个独特的编码来存取数据的
  4.                                                    //也可以*其他数的 自己定的。
  5. }

复制代码

作者: 山水游客    时间: 2012-7-25 13:12
使用HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的 hash code 值是否与增加的对象的hash code 值一致;如果不一致,直接加进去;如 果一致,再进行equals 方法的比较,equals 方法如果返回true ,表示对象已经加进 去了,就不会再增加新的对象,否则加进去.
作者: 杨康    时间: 2012-7-25 13:52
对于复写了Object中的hashCode()方法,在方法体中,如何能确定这个hashCode()返回的值在内存中是唯一的,所以复写后的hashCode()将判断依据经过算法,然后得到一个值,
return 中的+ age*34  假如两个对象的name是相同的,那么给其后面加上每个对象自己的属性age*x,就可以基本保证这两个值的和是一唯一的,用+而不用*或者其他的,是为了返回的数值在int范围呢.所以+ age*34  这一部分方法体,可以随便定义,只要满足最后的值在int范围内即可.
作者: 高欢欢    时间: 2012-7-26 10:37
hashcode默认情况下是对象的内存地址值(String除外)

2.hashcode在集合中,根据POJO对象的属性值判断对象是否相等时经常会用

3.重写hashcode和equals方法,根据对象的属性值可以生成相同的hashcode值,然后再比较equals方法来比较对象是否相同

这样覆盖了hashcode方法以后就会造成不同内存地址的对象会有相同的hashcode值

但是内存地址相同的对象hashcode值是一定相同的



作者: 罗宵    时间: 2012-7-26 11:35
hashCode在Object中一般是通过将该对象的内部地址转换成一个整数来实现的。所以一般对象不同的话,返回的hash值是不同的。但是很多时候我们需要根据自己
的要求定义两个对象是否相同。
比如定义姓名,年龄相同的两个对象是同一个对象。这时候就要从写hashCode()方法了,然后在从写equals()方法,比较对象的属性。看是否相同。确定这两个对象是否相同。
作者: 吴立杰    时间: 2012-7-26 13:34
楼主要理解HashSet的数据结构是hash表的,你存进去的时候会默认走hashcode算法,这个算法是根据这个对象的地址值随机产生的,hash表结构为了提高效率,将内存分了很多区域,如图可知:对象是被分区放进内存的,如果两个对象的地址值根据hashcode的算法相同了,那么它们会被放在同一个区域中,而重写hashcode和equals是我们想按照我们自己的方式来去除hashset内认为重复的内容。
还有一点楼主要记住:重写hashcode时,内部如果使用到了该类的字段,那么后期最后不要再修改这些字段的值了,因为如果修改了,会造成存入hashset内的这个对象隐藏,这是有可能造成内存泄露的。

360截图20120726131743281.jpg (62.57 KB, 下载次数: 62)

360截图20120726131743281.jpg





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