黑马程序员技术交流社区
标题:
请教大家关于内存泄露的问题
[打印本页]
作者:
陈国斌
时间:
2013-5-3 18:32
标题:
请教大家关于内存泄露的问题
一个对象存放在HashSet集合中后,再把它的某个属性值改掉,会导致删除该对象的动作失败,于是发生内存泄露,我想请问一下,具体的原因是下列哪种?
1、对象属性值的改变导致对象哈希值的变化,紧接着对象按照新的哈希值在集合中有了新的位置,而删除时,又是按照原来的位置去找,导致删除失败。
2、对象属性值的改变导致对象哈希值的变化,在删除时,按照新的哈希值对应的位置去找,而对象仍存在于原来的位置上,所以导致删除失败。
或者是其他的原因?
有什么办法能让更改某个属性值后,仍然能正常删除?请高手指点,感激不尽!
作者:
陈国斌
时间:
2013-5-3 20:52
尹桥印 发表于 2013-5-3 18:44
楼主又在找茬了。呵呵,楼主的帖子我觉得我都应该要收藏,因为问的问题都好有深度。先收藏了先 ...
哥们你再这么说,我都不敢问问题了,呵呵!我还是个刚开始学的菜鸟
作者:
刘胜寒
时间:
2013-5-3 21:24
本帖最后由 刘胜寒 于 2013-5-3 21:32 编辑
对象的属性改变并没有立刻改变hash值的变化。
只是当去调用remove的时候才会改变hash值的变化。
class A
{
int x,y;
A(int x,int y)
{
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
System.out.println(x+":"+y);
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals");
if (this == obj)
{
return true;
}
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
public class Test{
public static void main(String[] arg)
{
HashSet<A> B = new HashSet<A>();
A A1 = new A(2,3);
A A2 = new A(3,2);
A A3 = new A(3,4);
A A4 = new A(4,3);
B.add(A1);
B.add(A2);
B.add(A3);
B.add(A4);
A4.x=7;
System.out.println("A4 被修改");
System.out.println(A4.x+"::::"+A4.y);
System.out.println(B.contains(A4));
System.out.println(B.remove(A4));
}
复制代码
hasset的源码
<blockquote> public boolean remove(Object o) {
复制代码
看看是怎么现实remove的。通过正常途径添加到hashset的有一个固定一个标识PRESENT,当你的某属性改变的时候,标识肯定不是PRESENT。然后导致删除失败。
按照新的哈希值对应的位置去找,而对象仍存在于原来的位置上。
作者:
杨同旺
时间:
2013-5-4 08:39
答案是:
对象属性值的改变导致对象哈希值的变化,在删除时,按照新的哈希值对应的位置去找,而对象仍存在于原来的位置上,所以导致删除失败。
要想改变对象的属性,又能正常删除,明白删除对象依据hashCode去找的,而hashCode又是根据属性值来计算的,
所以,只要覆写的hashCode()方法中不使用你要改的那个属性即可,那你再改这个属性,就不影响hashCode的值了,所以也不影响集合找对象了,也可以查找和删除了.
作者:
黄玉昆
时间:
2013-5-4 22:57
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2