本帖最后由 黄敏 于 2012-8-24 19:23 编辑
杜鹏云 发表于 2012-8-24 17:14
这个我感觉是引用错了内存中的地址,,但是这个和内存泄露有什么关系?? ...
import java.util.HashSet;
public class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
Person p1 = new Person("a1",11);
Person p2 = new Person("a2",12);
Person p3 = new Person("a3",13);
Person p4 = new Person("a1",11);
hs.add(p1); //p1存进hs中的时候根据你覆写hashCode方法算出来的“name.hashCode()+age*37”值存到到集合中分配的对应的区域块(暂且认为是区域01)中,这时你的算出来的hashCode应该是name.hashCode()+11*37.
hs.add(p2);
hs.add(p3);
//hs.add(p4);
p1.setAge(15); //你设置了pi的年龄是15,又根据算出来的值是name.hashCode()+15*37.
hs.remove(p1); //当你要在集合中移除p1的时候,还是根据hashCode的值去集合中查找与之对应的p1,但是刚刚你上面改变了p1的年龄,算出来的hashCode值肯定不一样了 这个集合就会根据你刚刚的值去内存中对应的区域块查,发现没有对应的pi就没删了,这时的区域01就在集合成垃圾了,即使你把改后的p1添加到集合中,存起来的也是不同的区域,你删除的p1还不是区域01,还是垃圾
假如你现在往集合里添加了对象很多,不断地重复刚才的添加,修改,删除操作,上述的垃圾就一直增加,内存空间就越来越少,导致内存溢出。就是张老师说的如果参加hashCode运算的变量在HashSet集合中添加了,就不要随意修改,希望能帮助你理解
System.out.println(hs.size());
}
}
class Person
{
private String name;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public int hashCode()
{
return name.hashCode()+age*37;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
|