Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

1.6. Map

		
Map
 ├Hashtable
 ├HashMap
 └WeakHashMap
 
 Map介面
  請注意,Map沒有繼承Collection介面,Map提供key到value的映射。一個Map中不能包含相同的key,每個key只能映射一個 value。Map介面提供3種集合的視圖,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value映射。
Hashtable類
  Hashtable繼承Map介面,實現一個key-value映射的哈希表。任何非空(non-null)的對象都可作為key或者value。
  添加數據使用put(key, value),取出數據使用get(key),這兩個基本操作的時間開銷為常數。
Hashtable通過initial capacity和load factor兩個參數調整性能。通常預設的load factor 0.75較好地實現了時間和空間的均衡。增大load factor可以節省空間但相應的查找時間將增大,這會影響像get和put這樣的操作。
使用Hashtable的簡單示例如下,將1,2,3放到Hashtable中,他們的key分別是”one”,”two”,”three”:
    Hashtable numbers = new Hashtable();
    numbers.put(“one”, new Integer(1));
    numbers.put(“two”, new Integer(2));
    numbers.put(“three”, new Integer(3));
  要取出一個數,比如2,用相應的key:
    Integer n = (Integer)numbers.get(“two”);
    System.out.println(“two = ” + n);
  由於作為key的對象將通過計算其散列函數來確定與之對應的value的位置,因此任何作為key的對象都必須實現hashCode和equals方 法。hashCode和equals方法繼承自根類Object,如果你用自定義的類當作key的話,要相當小心,按照散列函數的定義,如果兩個對象相 同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個對象不同,則它們的hashCode不一定不同,如 果兩個不同對象的hashCode相同,這種現象稱為衝突,衝突會導致操作哈希表的時間開銷增大,所以儘量定義好的hashCode()方法,能加快哈希 表的操作。
  如果相同的對象有不同的hashCode,對哈希表的操作會出現意想不到的結果(期待的get方法返回null),要避免這種問題,只需要牢記一條:要同時複寫equals方法和hashCode方法,而不要只寫其中一個。
  Hashtable是同步的。
HashMap類
  HashMap和Hashtable類似,不同之處在於HashMap是非同步的,並且允許null,即null value和null key。,但是將HashMap視為Collection時(values()方法可返回Collection),其迭代子操作時間開銷和HashMap 的容量成比例。因此,如果迭代操作的性能相當重要的話,不要將HashMap的初始化容量設得過高,或者load factor過低。
WeakHashMap類
  WeakHashMap是一種改進的HashMap,它對key實行“弱引用”,如果一個key不再被外部所引用,那麼該key可以被GC回收。
		
	

1.6.1. 初始化

		
	Map<String, Object> data = new HashMap<String, Object>() {
		{
			put("name", "neo");
		}
	};		
		
		

1.6.2. static map

			
	private static final Map<String, String> point;
	static {
		point = new HashMap<String, String>();
		point.put("CN", "China");
		point.put("HK", "Hongkong");
		point.put("TW", "Taiwan");
	};
			
		
			
	public final static Map<String, String> hostMap = new HashMap<String, String>() {
        {
            put("redis", "127.0.0.1");
            put("solr", "127.0.0.1");
        }
	};
		
		
	public final static Map map = new HashMap() {{      
	    put("key1", "value1");      
	    put("key2", "value2");      
	}};  		
			
		

1.6.3. HashMap

1.6.3.1. 遍歷 HashMap

			
Map<String, Integer> session = new HashMap<String, Integer>();

session.put("A",1);
...
...
session.put("Z",26)

for (Map.Entry<String, Integer> entry : session.entrySet()) {
	System.out.println(String.format("%s:%d", entry.getKey(), entry.getValue()));
}

Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {  
  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
  
} 

			
			

1.6.3.2. 遍歷map中的鍵

			
Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  
//遍歷map中的鍵  
  
for (Integer key : map.keySet()) {  
  
    System.out.println("Key = " + key);  
  
}  			
			
			

1.6.3.3. 遍歷map中的值 

			
Map<Integer, Integer> map = new HashMap<Integer, Integer>();    
for (Integer value : map.values()) {  
    System.out.println("Value = " + value);  
}  			
			
			

1.6.3.4. 通過鍵取值

			
Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  
for (Integer key : map.keySet()) {  
  
    Integer value = map.get(key);  
  
    System.out.println("Key = " + key + ", Value = " + value);  
  
}  			
			
			

1.6.3.5. 使用 Iterator 遍歷 HashMap

			
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
  
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
  
while (entries.hasNext()) {
  
    Map.Entry<Integer, Integer> entry = entries.next();
  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
  
}  

Map map = new HashMap();  
  
Iterator entries = map.entrySet().iterator();
  
while (entries.hasNext()) {  
  
    Map.Entry entry = (Map.Entry) entries.next();  
  
    Integer key = (Integer)entry.getKey();  
  
    Integer value = (Integer)entry.getValue();  
  
    System.out.println("Key = " + key + ", Value = " + value);  
}  
			
			

1.6.4. LinkedHashMap

		
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
public class TestLinkedHashMap {
 
  public static void main(String args[])
  {
   System.out.println("*** LinkedHashMap ***");
   Map<Integer,String> map = new LinkedHashMap<Integer,String>();
   map.put(6, "apple");
   map.put(3, "banana");
   map.put(2,"pear");
   
   for (Iterator it =  map.keySet().iterator();it.hasNext();)
   {
    Object key = it.next();
    System.out.println( key+"="+ map.get(key));
   }
   
   System.out.println("*** HashMap ***");
   Map<Integer,String> map1 = new  HashMap<Integer,String>();
   map1.put(6, "apple");
   map1.put(3, "banana");
   map1.put(2,"pear");
   
   for (Iterator it =  map1.keySet().iterator();it.hasNext();)
   {
    Object key = it.next();
    System.out.println( key+"="+ map1.get(key));
   }
  }
}
		
		

1.6.5. Map forEach

		
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);

items.forEach((k,v)->System.out.println("key : " + k + "; value : " + v));

//output
key : A value : 10
key : B value : 20
key : C value : 30
key : D value : 40
key : E value : 50
key : F value : 60

items.forEach((k,v)->{
    System.out.println("key : " + k + " value : " + v);
});