文档章节

Java中的覆盖hashcode造成内存泄漏的原因

o
 onedotdot
发布于 2017/08/28 16:19
字数 1058
阅读 6
收藏 0

如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息。如果是一个集合中有很多元素,譬如有一万个元素,并且没有包含要查找的对象时,则意味着你的程序需要从该集合中取出一万个元素进行啄一的比较才能得到结论,有人发明了一种hashCode算法,来提高查找的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域,

 

 

hashSet就是采用哈希算法存储对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组的划分对象的存储区域。Object中的hashCode用来返回对就java对象的哈希码,从而提高查找的效率。

 

为了保证一个类的实例对象能在HashSet正常存储,要求这个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,也就是说,如果obj1.equals(obj2)的结果为true,那么一下表达式的结果页要为true。

obj1.hashCode() == obj2.hashCode()

如果一个类的hashCode()方法没有遵循上述要求,那么,当这个的两个实例对象用equals()方法比较的结果相等时,它们本来应该无法同时存储进Set集合中,但是,如果将它们存储进HashSet集合中时,由于它们的hashCode()方法的返回值不同,第二个对象首先按哈希码计算可能会被放进与第一个对象不同的区域中,这样,它就不可能与第一个对象进行equals方法比较了,也就可能被存储进HashSet集合中了。Object类的hashCode()方法不能满足对象被存入到HashSet中的要求,因为它的返回值是通过对象的内存地址推算出来的,同一个对象在程序运行期间的任何时候返回的哈希值都是始终不变的,所以,只要是两个不同的实例对象,即使它们的equals方法比较结果相等,它们默认的hashCode方法的返回值是不同的。

提示:

(1)通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即euqlas方法比较结果不相等的对象可以有相同的哈希码,或者说哈希码相同的两个对象的equals方法比较的结果可以不等,例如,字符串“BB”和"Aa"的euqals方法比较结果肯定不相等,但它们的hashCode方法返回值却相等。

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

 

附录:

    hashset判断相等的步骤如下:

1、判断hash值是否相等;如果相等,在判断是否equals相等;所以不能修改参与hash值的字段;因为一旦修改,那个元素就永远存在集合里面,但是没法找到,因为已经没法定位了,这样就会造成内存泄露;

 

本文转载自:http://blog.csdn.net/huangbiao86/article/details/6387938

共有 人打赏支持
o
粉丝 6
博文 330
码字总数 14350
作品 0
朝阳
最最最常见的Java面试题总结-第一周

这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。 Github地址:https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试...

Amsour丶
08/08
0
0
hashCode与equals的区别与联系

一、equals方法的作用 1、默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对...

期待变强的菜鸟
2014/04/09
0
1
Java拾遗:001 - 重写 equals 和 hashCode 方法

重写equals方法 在Java中Object类是一个具体类,但它设计的主要目的是为了扩展,所以它的所有非final方法,都被设计成可覆盖(override)的。但任何一个子类在覆盖这些方法时都应遵守一些通用...

一别丶经年
08/02
0
0
去投资银行面试会遇到的10个Java问题

本文由ImportNew -大瓜细瓜 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 很多Java开发人员会到巴克莱、瑞士信贷、花旗等投资银行申请Java开发职位,但他们中很多人都不知道面试时会遇...

ImportNew
07/25
0
0
分享一份非常强势的Android面试题

马上步入金九银十了,是时候看一些面试题去鹅厂了,接下来我将分享一些面试题,每天总结一点点,希望对大家有所帮助! ListView和RecyclerView区别 参考链接: blog.csdn.net/shu_lance/a… ...

codeGoogle
08/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

利用碎片化时间Get Linux系统

起初,我做着一份与IT毫无关系的工作,每月领着可怜的工资,一直想改变现状,但无从下手,也就是大家熟知的迷茫。我相信,每一个人都会或多或少的经历过迷茫,迷茫每一个选择,迷茫工作或者生...

linuxprobe16
18分钟前
0
0
OSChina 周日乱弹 —— 恨不得给你买张飞机挂票

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @开源中国首席灵魂师:分享张希/曹方的单曲《认真地老去》 来不及认真的年轻过,就认真的老去! 《认真地老去》- 张希/曹方 手机党少年们想听...

小小编辑
今天
168
6
如何实现靠谱的分布式锁?

分布式锁,是用来控制分布式系统中互斥访问共享资源的一种手段,从而避免并行导致的结果不可控。基本的实现原理和单进程锁是一致的,通过一个共享标识来确定唯一性,对共享标识进行修改时能够...

郑加威
今天
2
0
Mac OS X下Maven的安装与配置

Mac OS X 安装Maven: 下载 Maven, 并解压到某个目录。例如/Users/robbie/apache-maven-3.3.3 打开Terminal,输入以下命令,设置Maven classpath $ vi ~/.bash_profile 添加下列两行代码,之后...

TonyStarkSir
今天
3
0
关于编程,你的练习是不是有效的?

最近由于工作及Solution项目的影响,我在重新学习DDD和领域建模的一些知识。然后,我突然就想到了这个问题,以及我是怎么做的? 对于我来说,提升技能的项目会有四种: 纯兴趣驱动的项目。即...

问题终结者
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部