首先在建立一个配置文件config.properties
package javatribe.fts.reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
public class ReflectTest3 {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//InputStream ips=new FileInputStream("config.properties");
//InputStream ips=ReflectTest3.class.getClassLoader().getResourceAsStream("javatribe/fts/reflect/config.properties");
InputStream ips=ReflectTest3.class.getResourceAsStream("resources/config.properties");
Properties props=new Properties();
props.load(ips);
ips.close();
String className=props.getProperty("className");
Collection cllections=(Collection) Class.forName(className).newInstance();
ReflectPoint pt1=new ReflectPoint(3,3);
ReflectPoint pt2=new ReflectPoint(5,5);
ReflectPoint pt3=new ReflectPoint(3,3);
cllections.add(pt1);
cllections.add(pt2);
cllections.add(pt3);
cllections.add(pt1);
System.out.println(cllections.size());
}
}
如果配置文件写:className=java.util.HashSet 则输出结果是2
如果配置文件写:className=java.util.ArrayList 则输出结果是4
这是为什么呢?
ArrayList是有序集合,相当于数组。存放的是外面对象的引用。这里对象可以重复。而HashSet存放的对象不能重复
这个时候得分析一下hashCode的用处了,下面用简单代码说明?
package javatribe.fts.reflect;
public class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
public ReflectPoint(int x, int y) {
super();
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;
final ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString(){
return str1+" : "+str2+" : "+str3;
}
}
package javatribe.fts.reflect;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class ReflectTest2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//Collection cllections=new ArrayList();
Collection cllections=new HashSet();
ReflectPoint pt1=new ReflectPoint(3,3);
ReflectPoint pt2=new ReflectPoint(5,5);
ReflectPoint pt3=new ReflectPoint(3,3);
cllections.add(pt1);
cllections.add(pt2);
cllections.add(pt3);
cllections.add(pt1);
//pt1.y=7;
//cllections.remove(pt1);
System.out.println(cllections.size());
}
}
这个时候输出的结果是2
要是我打开注释呢?
//pt1.y=7;
//cllections.remove(pt1);
输出结果依旧是2
如果我我打开注释呢?
//cllections.remove(pt1);
输出的结果是1
这是为什么呢?
hashcode在存储值得时候把数值分为若干值域,把将要存入的数据转化为HashCode码(通过一定的算法得到)后放入不同的区域,当有相同的对象的时候也根据hash算法算出具体的值,根据具体的值在对用的区域去匹配,而不是一个一个从头开始匹配,这样提高了存储效率。
当对象被存储进HashCode集合中以后,就不能修改这个对象中的那些参与计算哈希值得字段,否则,对象修改后的哈希值与最近存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains 方法使用该对象当前的引用作为参数去HashSet集合检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露