当一个对象被存储进HashSet集合中以后,就不能修改这个对象中那些参与计算哈希值的字段了,否则,对象修改以后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果(字段值一改变,hashcode就会改变,相应的引用地址也会改变,导致以前的引用作废),这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。
package staticImport.cn.itcast.day1; import java.io.FileInputStream; import java.io.InputStream; import java.util.Collection; import java.util.HashSet; import java.util.Properties; public class ReflectTest2 { public static void main(String args[])throws Exception{ /**已经知道集合类型*/ Collection<ReflectPoint> collections = new HashSet<ReflectPoint>(); ReflectPoint pt1 = new ReflectPoint(3,3); ReflectPoint pt2 = new ReflectPoint(5,3); ReflectPoint pt3 = new ReflectPoint(3,3); collections.add(pt1); collections.add(pt2); collections.add(pt3); collections.add(pt1); /*1、当重写了ReflectPoint中的hashCode与equals方法之后pt4就存不到collections中了 这时候,size的值为2*/ /*某一个对象存入到集合中之后,参与hashCode运算的属性就不要改动了,改完之后就会造成内存泄露。如果不断的在 * 集合中添加对象,修改对象,删除对象,以此循环,最终的结果就是内存溢出*/ pt1.y = 9;//修改属性y导致pt1的hashCode改变,以前的引用变得没有作用,导致remove不掉 System.out.println(collections.remove(pt1));//false System.out.println(collections.size()); } }
class ReflectPoint{
private int x;
public int y;
public String str1 = "basketball";
protected String str2 = "aaaaaaaaaaCCCCCCCC";
public String str3 = "ababababa";
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString(){
return str1+" "+str2+" "+str3;
}
//在ReflectTest2中要使用
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
}
|