标签:内存 arraylist hashcode 内存泄露 equals
首先,我们需要知道的是ArrayList和HashSet类都在java.util包中,都是实现了Collection的类,Collection是一个标准。
然后,我们介绍下这两个类之间的区别:
1、ArrayList:相当于一个动态的数组,是一组有序的集合,当对象被添加到ArrayList时,对象会先找到第一个空缺的地方。这里有一点需要记得:放进去的是对象的引用,不是对象本身。然后,放入第二个对象,如果和第一个相同的话,依然按照顺序存放进去。也就是说,在这个有序集合里,每有一个对象就会放入一个引用,可能出现多个引用指向同一个对象的情况,但没有关系。
package com.internet;
import java.util.ArrayList;
public class test {
public static void main(String[] args){
ArrayList c = new ArrayList();
Integer a = new Integer(1);
Integer b = new Integer(1);
c.add(a);
c.add(b);
System.out.println(c.size()); //结果:2
System.out.println(a.equals(b));//结果为true,可以看出两个对象是相等的
}
}
2、HashSet:当放入对象时,首先查看里面是否有这样一个对象(这里判定的是对象的地址是否相同),如果有,则不放,如果没有才会放入:
MyTest.java
package com.internet;
class MyTest
{
int x;
int y;
public MyTest(int x,int y)
{
this.x=x ;
this.y=y ;
}
}ReflectTest.java
package com.internet;
import java.util.HashSet;
public class ReflectTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
MyTest t1 = new MyTest(1, 1);
MyTest t2 = new MyTest(2, 2);
MyTest t3 = new MyTest(1, 1);
hs.add(t1);
hs.add(t2);
hs.add(t3);
hs.add(t1);
System.out.println(hs.size()); //结果:3
}
}
在这里,需要注意一点:在FlectTest.java中,声明了t3对象,这里的t3与t1的构造的x,y值相同,但是t1和t3都存入了hs中,
就是因为,这里说的是否有相同的对象指的是内存地址,不是数值。
其次,紧接上边的HashSet的例子,如果我们需要让t1和t3是相同,在t1存进去之后t2不能够存进去,应怎么办呢?
我们需要在MyTest.java中覆盖equals()方法:
package com.internet;
import java.util.*;
class MyTest1
{
int x;
int y;
public MyTest1(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;
MyTest1 other = (MyTest1) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}然后,在FlectTest.java中得到的结果就是2了。
具体该怎么覆盖呢?在MyTest.java代码窗口点击右键------>找到“Source"并点击------->找到”Generate hashCode() and equals()"并点击。
还有,在对象中覆盖了equals()方法之后,当一个对象存储进了HashSet集合之中后,就不能够修改这个对象中参与计算哈希值的字段了。否则,对象修改后的哈希值与最初存进HashSet集合中的哈希值就不同了。这时,如果要删除某个存进去的对象,就不能够通过哈希值正确删除了,从而造成内存泄露。
package com.internet;
import java.util.*;
public class ReflectTest4
{
public static void main(String[]args)
{
//面向父类的编程或者面向接口编程
Collection c1=new HashSet() ;
MyTest1 t1=new MyTest1(2,2) ;
MyTest1 t2=new MyTest1(3,4) ;
MyTest1 t3=new MyTest1(2,2) ;
c1.add(t1) ;
c1.add(t2) ;
c1.add(t3) ;
c1.add(t1) ;
System.out.println(c1.size()); //结果:2
t1.x =4;
c1.remove(t1);
System.out.println(c1.size()); //结果:2
}
}由上边我们可以看到,t1对象没有被正确删除。因为程序修改了t1中能够生成hashcode的值x,导致生成的hashcode与存进去的不一致,不能删除。
java基础巩固系列(五):ArrayList与HashSet的比较,以及HashCode分析
标签:内存 arraylist hashcode 内存泄露 equals
原文地址:http://blog.csdn.net/u010800530/article/details/38796771