黑马程序员技术交流社区

标题: 关于hashCode()与内存泄露的问题 [打印本页]

作者: 刘焕新    时间: 2013-3-30 13:25
标题: 关于hashCode()与内存泄露的问题
本帖最后由 刘焕新 于 2013-3-31 22:29 编辑

视频学习到“26_黑马程序员_张孝祥_Java基础加强_ArrayList_HashSet的比较及Hashcode分析.avi”,有如下疑问:
先看视频中的示例代码:
  1. Collection collections = new HashSet();

  2. //定义三个对象
  3. ReflectPoint pt1 = new ReflectPoint(3,3);
  4. ReflectPoint pt1 = new ReflectPoint(5,5);
  5. ReflectPoint pt1 = new ReflectPoint(3,3);

  6. //往集合里添加对象
  7. collections.add(pt1);
  8. collections.add(pt2);
  9. collections.add(pt3);
  10. collections.add(pt1);
  11. System.out.println(collections.size()); //重写了ReflectPoint类的hashCode()和equals(),所以打印的结果是2

  12. pt1.x = 7; //修改pt1对象中的字段值
  13. collections.remove(pt1);  //将pt1对象从集合中删除掉
  14. System.out.println(collections.size()); //打印的结果还是2
复制代码
以下的理解对不对,是这样的吗?
所谓的内存泄露:当一个对象不再被使用后,它占用的内存无法得到释放,CG无法回收它。
hashSet的原理:当要将一个对象存入HashSet集合时,会先调用对象的hashCode()和equals()进行运算和比较,最后真正存入集合的是对象的哈希值与对象的地址引用。

还有,示例中,内存泄露的现象,是不是因为重写了hashCode()方法造成的?如何避免这种内存泄露呢?

作者: 王俊杰    时间: 2013-3-30 13:36
本帖最后由 王俊杰 于 2013-3-30 13:40 编辑

由于我实际上还没有看这个视频,所以帮你查了一下。

希望对你有帮助。如何避免内存泄漏,这一点我也没有好的办法。希望能看到富有启发性的回复。

关于HashCode和内存泄漏的问题。如果不想将参数相同的对象存入HashSet,可以重写hashCode方法和equals方法。需要返回相同的hashCode,才能判断对象相等。当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄漏。部分代码展示:
  1. public static void main(String[] args) throws Exception {
  2.   ReflectPoint r1 = new ReflectPoint(123,"kenny");
  3.   ReflectPoint r2 = new ReflectPoint(12123,"kenny");
  4.   ReflectPoint r3 = new ReflectPoint(113,"kdfny");
  5.   ReflectPoint r4 = new ReflectPoint(123,"kenny");
  6.   Collection coll = new HashSet();
  7.   coll.add(r1);
  8.   coll.add(r2);
  9.   coll.add(r3);
  10.   coll.add(r4);
  11.   coll.add(r1);
  12.   r2.name = "df";//如果在此处修改了name,那么同时就改了r2的hashcode,
  13.   //所以下面的语句就不能删除r2了,而是删除了其它东西。这也叫内存泄漏。
  14.   coll.remove(r2);
  15.   System.out.println(coll.size());
  16. ××××××××××××××××××
  17. public class ReflectPoint {

  18. private int password;
  19. String name;
  20. public ReflectPoint(int password, String name) {
  21.   super();
  22.   this.password = password;
  23.   this.name = name;
  24. }
  25. @Override
  26. public int hashCode() {
  27.   final int prime = 31;
  28.   int result = 1;
  29.   result = prime * result + ((name == null) ? 0 : name.hashCode());
  30.   result = prime * result + password;
  31.   return result;
  32. }
  33. @Override
  34. public boolean equals(Object obj) {
  35.   if (this == obj)
  36.    return true;
  37.   if (obj == null)
  38.    return false;
  39.   if (getClass() != obj.getClass())
  40.    return false;
  41.   ReflectPoint other = (ReflectPoint) obj;
  42.   if (name == null) {
  43.    if (other.name != null)
  44.     return false;
  45.   } else if (!name.equals(other.name))
  46.    return false;
  47.   if (password != other.password)
  48.    return false;
  49.   return true;
  50. }


  51. }
复制代码
声明:以上内容非本人原创。
详细请参考http://blog.csdn.net/yinkai1205/article/details/6254782 在此谨向yinkai1205致敬!
作者: 陈丽莉    时间: 2013-3-31 22:11
还有问题的话,继续追问;没有的话,请将帖子分类改成【已解决】~




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