Java為數據結構中的映射定義了壹個接口java.util.Map,
它有四個實現類,分別是HashMap、HashTable、LinkedHashMap和TreeMap。
這裏介紹這4中實例的用法和區別。
關鍵技術剖析:
Map用於存儲鍵值對,根據鍵得到值,因此不允許鍵重復,值可以重復。
l ?(1)HashMap是壹個最常用的Map,它根據鍵的hashCode值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許壹條記錄的鍵為null,不允許多條記錄的值為null。HashMap不支持線程的同步,即任壹時刻可以有多個線程同時寫HashMap,可能會導致數據的不壹致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。
l ?(2)Hashtable與HashMap類似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任壹時刻只有壹個線程能寫Hashtable,然而,這也導致了Hashtable在寫入時會比較慢。
l ?(3)LinkedHashMap保存了記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的。在遍歷的時候會比HashMap慢。有HashMap的全部特性。
l ?(4)TreeMap能夠把它保存的記錄根據鍵排序,默認是按升序排序,也可以指定排序的比較器。當用Iteraor遍歷TreeMap時,得到的記錄是排過序的。TreeMap的鍵和值都不能為空。
import?java.util.HashMap;import?java.util.Hashtable;
import?java.util.Iterator;
import?java.util.LinkedHashMap;
import?java.util.Map;
import?java.util.TreeMap;
public?class?TestMap?{
public?static?void?init(Map?map){
if?(map?!=?null){ String?key?=?null; for?(int?i=5;?i>0;?i--){key?=?new?Integer(i).toString()?+?".0";
map.put(key,?key.toString());
//Map中的鍵是不重復的,如果插入兩個鍵值壹樣的記錄,
//那麽後插入的記錄會覆蓋先插入的記錄
map.put(key,?key.toString()?+?"0");?}
}}
public?static?void?output(Map?map){
if?(map?!=?null){ Object?key?=?null; Object?value?=?null; //使用叠代器遍歷Map的鍵,根據鍵取值 Iterator?it?=?map.keySet().iterator(); while?(it.hasNext()){key?=?it.next();
value?=?map.get(key);
System.out.println("key:?"?+?key?+?";?value:?"?+?value?);
} //或者使用叠代器遍歷Map的記錄Map.Entry Map.Entry?entry?=?null; it?=?map.entrySet().iterator(); while?(it.hasNext()){//壹個Map.Entry代表壹條記錄
entry?=?(Map.Entry)it.next();
//通過entry可以獲得記錄的鍵和值
//System.out.println("key:?"?+?entry.getKey()?+?";?value:?"?+?entry.getValue());
} }}
public?static?boolean?containsKey(Map?map,?Object?key){
if?(map?!=?null){ return?map.containsKey(key); } return?false;}
public?static?boolean?containsValue(Map?map,?Object?value){
if?(map?!=?null){ return?map.containsValue(value); } return?false;}
public?static?void?testHashMap(){
Map?myMap?=?new?HashMap(); init(myMap); //HashMap的鍵可以為null myMap.put(null,"ddd"); //HashMap的值可以為null myMap.put("aaa",?null); output(myMap);}
public?static?void?testHashtable(){
Map?myMap?=?new?Hashtable(); init(myMap); //Hashtable的鍵不能為null //myMap.put(null,"ddd"); //Hashtable的值不能為null //myMap.put("aaa",?null); output(myMap);}
public?static?void?testLinkedHashMap(){
Map?myMap?=?new?LinkedHashMap(); init(myMap); //LinkedHashMap的鍵可以為null myMap.put(null,"ddd"); myMap.put(null,"aaa"); //LinkedHashMap的值可以為null myMap.put("aaa",?null); output(myMap);}
public?static?void?testTreeMap(){
Map?myMap?=?new?TreeMap(); init(myMap); //TreeMap的鍵不能為null //myMap.put(null,"ddd"); //TreeMap的值不能為null //myMap.put("aaa",?null); output(myMap);}
public?static?void?main(String[]?args)?{
System.out.println("采用HashMap"); TestMap.testHashMap(); System.out.println("采用Hashtable"); TestMap.testHashtable(); System.out.println("采用LinkedHashMap"); TestMap.testLinkedHashMap(); System.out.println("采用TreeMap"); TestMap.testTreeMap(); Map?myMap?=?new?HashMap(); TestMap.init(myMap); System.out.println("新初始化壹個Map:?myMap"); TestMap.output(myMap); //清空Map myMap.clear(); System.out.println("將myMap?clear後,myMap空了麽"?+?myMap.isEmpty()); TestMap.output(myMap); myMap.put("aaa",?"aaaa"); myMap.put("bbb",?"bbbb"); //判斷Map是否包含某鍵或者某值 System.out.println("myMap包含鍵aaa"+?TestMap.containsKey(myMap,?"aaa")); System.out.println("myMap包含值aaaa"+?TestMap.containsValue(myMap,?"aaaa")); //根據鍵刪除Map中的記錄 myMap.remove("aaa"); System.out.println("刪除鍵aaa後,myMap包含鍵aaa"+?TestMap.containsKey(myMap,?"aaa")); //獲取Map的記錄數 System.out.println("myMap包含的記錄數:?"?+?myMap.size());}
}
輸出結果:
采用HashMap
key: null; value: ddd
key: 3.0; value: 3.00
key: aaa; value: null
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
采用Hashtable
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 3.0; value: 3.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
采用LinkedHashMap
key: 5.0; value: 5.00
key: 4.0; value: 4.00
key: 3.0; value: 3.00
key: 2.0; value: 2.00
key: 1.0; value: 1.00
key: null; value: aaa
key: aaa; value: null
采用TreeMap
key: 1.0; value: 1.00
key: 2.0; value: 2.00
key: 3.0; value: 3.00
key: 4.0; value: 4.00
key: 5.0; value: 5.00
新初始化壹個Map: myMap
key: 3.0; value: 3.00
key: 4.0; value: 4.00
key: 1.0; value: 1.00
key: 5.0; value: 5.00
key: 2.0; value: 2.00
將myMap clear後,myMap空了麽 true
myMap包含鍵aaa true
myMap包含值aaaa true
刪除鍵aaa後,myMap包含鍵aaa false
myMap包含的記錄數: ?1
源碼分析:
遍歷Map有兩種方法:
(1)map的keySet()方法獲得鍵的集合,再調用鍵集合的iterator方法獲得鍵的叠代器,以此叠代地取出Map中的鍵,用get方法獲得鍵對應的值,便完成了Map的遍歷。代碼如下所示:
//使用叠代器遍歷Map的鍵,根據鍵取值
Iterator it = map.keySet().iterator();
while (it.hasNext()){
? key = it.next();
? value = map.get(key);
? System.out.println("key: " + key + "; value: " + value );
}
(2)使用Map的entrySet方法獲得Map中記錄的集合,每條對象都是壹個Map.Entry對象,使用其getKey方法獲得記錄的鍵,使用其getValue方法獲得記錄的值。代碼如下所示:
//或者使用叠代器遍歷Map的記錄Map.Entry
Map.Entry entry = null;
it = map.entrySet().iterator();
while (it.hasNext()){
? //壹個Map.Entry代表壹條記錄
? entry = (Map.Entry)it.next();
? //通過entry可以獲得記錄的鍵和值
? //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());