首先在建立一個配置文件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集合中單獨刪除當前對象,從而造成內存泄露