package com.sg.reflex;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class ReflexClassTest02 {
public static void main(String[] args) {
Collection collections = new HashSet();
//Collection collections = new ArrayList();
ReflecClassPoint rcp1 = new ReflecClassPoint(3, 3);
ReflecClassPoint rcp2 = new ReflecClassPoint(5, 5);
ReflecClassPoint rcp3 = new ReflecClassPoint(3, 3);
//因为没有重写equals和hashCode方法 所以现在rcp1 和 rcp3不相等
//把这些对象 放到集合中去
collections.add(rcp1);
collections.add(rcp2);
collections.add(rcp3);
collections.add(rcp1);
//修改rcp1.y的值
rcp1.y = 7;
//删除这个对象
collections.remove(rcp1);
System.out.println(collections.size());
}
}
class ReflecClassPoint{
private int x;
public int y ;
public ReflecClassPoint(int x, int y) {
this.x = x;
this.y = y;
}
@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;
ReflecClassPoint other = (ReflecClassPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString() {
return null;
}
//在这里因为没有重写equals和hashCode方法
//ArrayList是有位置顺序的 可以重复的 所以结果长度是 4
//HashSet是无位置顺序的 不可以重复的 所以结果长度是 3
//如果重写equals和hashCode方法 之后 现在rcp1 和 rcp3相等
//HashSet结果就是 2
//针对Set集合来说
//要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢
//equals比较是两个对象的值是否相等 但是并没有比较hashCode的在内存中的
//地址区域是否也是相等的
//根据上述例子 如果你把hashCode的方法 去掉 HashSet 依然打印的长度还是 3
//原因就是 没有去比较这两个对象在内存中的区域是否也是相同的
//反之 如果你把equals方法 去点也是一个道理 就是说去过这两个对象equals
//相等 你要去重写他们的hashCode方法 这样才能保证 两个对象是否是真的相等了
//前提是你这个对象存到的是一个Hash集合里 否则 就没有必要比较他们的hash地址是否相等了
//还有就是但一个对象被存在hashSet集合钟以后 就不能修改这个对象中那些参与计算的哈希
//算法的字段了 否则,对象修改之后的哈希值与最初存储进hashSet集合中的哈希值就不同了
//在这种情况下 即使你去删除这个对象时 也会删除不掉了 此时 他已经找不到这个对象了
//这也会导致无法从hashSet集合中单独的删除当前的对象了 从而导致内存泄露
//如果在重写了equals和hashCode方法 之后操作下面这些步骤的话:
//比如上面的rcp1对象 在把他放进hashSet集合之后 你去修改他的参数值 时 然后 再去删除
//remove这个rcp1对象 此时是删除不了的 此时通过HashSet集合的长度依然是 2
//如果你去再放进hashSet集合后的rcp1对象 直接删除的话
//此时通过HashSet集合的长度依然 就是 1
//如果通过上述这种情况操作的话 积累过多的话 可能会导致 内存泄漏的出现
//所以 一个对象被存在hashSet集合钟以后 就不要修改这个对象中那些参与计算的哈希
//算法的字段了
以上仅是个人通过小程序 对上述情况的说明与分析