HashSet就是采用哈希算法存储对象的,他内部采用了对某个数字进行取模的方式对所有的哈希码进行分组划分的对象存储区域
Object中定义了一个hashCode方法用来返回每个java对象的哈希码,当从hashSet集合中查找某个对象时,java系统首先调用对象的hashCode()方法获得该对象的哈希码,然后根据哈希码值找到相应的存储区域,最后取出该存储区域没的每个元素与该元素进行equals方法比较,这样不用遍历整个HashSet集合,就能得到结论。- public class ReflectPoint {
- String str1 = "sontao";//此处没有public
- public String str2 = "foxiaotao";
- public String str3 = "ou mygod";
- private int x;
- public int y;
- public ReflectPoint(int x, int y) {
- this.x = x;
- this.y = y;
- }
- public ReflectPoint(){}
- public String toString()
- {
- return str1+" : "+str2+" : "+str3;
- }
-
- @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 static void main(String[] args) {
- // TODO Auto-generated method stub
- Collection collections=null;
- try
- {
- // InputStream ips = new FileInputStream("config.properties");
- // InputStream ips = ArrayList_HashSet.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
- InputStream ips = ArrayList_HashSet.class.getResourceAsStream("resources/config.properties");
- Properties prop = new Properties();
- prop.load(ips);
- ips.close();
- String className = prop.getProperty("className");
- collections = (Collection)Class.forName(className).newInstance();
- }
- catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- ReflectPoint pt1 = new ReflectPoint(3,3);
- ReflectPoint pt2 = new ReflectPoint(4,4);
- ReflectPoint pt3 = new ReflectPoint(3,3);
- collections.add(pt1);
- collections.add(pt2);
- collections.add(pt3);//复写了ReflectPoint的hashCode方法和equals方法
- collections.add(pt1);
- pt1.y=7;
- collections.remove(pt1);//内存泄露,没能移除
- System.out.println(collections.size());
- }
- }
复制代码 结果:2
在例子中复写hashCode()和equals()方法,根据ReflectPoint的x,y的值确定对象的hashCode()值,这样pt1和pt3就是同一个对象,如果不复写hashCode(),pt1和pt3就不是同一个对象。
将pt1,pt2,pt3添加进集合中去之后,改变pt1.y的值
pt1.y=7;
这是从集合中移除pt1。
但是pt1在原来的HashSet中的存储位置已经由y值得改变而改变。程序这是不发现pt1新的位置。所以移除不出去,这样程序员以为移除了,但是pt1还在内存中,造成内存泄露。 |