1. 程式人生 > >java中的Map,回顧一下

java中的Map,回顧一下

Java8增強的Map集合

Map介面中定義瞭如下常用的方法。

void clear():刪除該Map物件中的所有key-value對。 
boolean containsKey(Object key):查詢Map中是否包含指定的key,如果包含則返回true。 
boolean containsValue(Object value):查詢Map中是否包含一個或多個value,如果包含則返回true。 
Set entrySet():返回map中包含的key-value對所組成的Set集合,每個集合元素都是map.Entry物件 
Object get(Object key):返回指定key所對應的value;如果此map中不包含該key,則返回null。 
boolean isEmpty():查詢該map是否為空,如果為空,則返回true。 
Set keySet():返回該map中所有key組成的set集合 
Object put(Object key,Object value):新增一個key-value對,如果當前map中已有一個與該key相等的key-value對,則新的key-value對會覆蓋原來的key-value對。 
void putAll(Map m):將指定map中的key-value對複製到本map中 
Object remove(Object key):刪除指定key所對應的key-value對,返回被刪除key所關聯的value,如果該key不存在,則返回null。 
boolean remove(Object key,Object value):這是java8新增的方法,刪除指定key,value所對應的key-value對,如果從該map中成功地刪除該key-value對,該方法返回true,否則返回false。 
int size():返回該map裡的key-value對的個數。 
collection values():返回該map裡所有value組成的collection。 
Map中包括了一個內部類Entry,該類封裝了一個key-value對。Entry包含如下三個方法。 
Object getKey():返回該Entry裡包含的key值 
Object getValue():返回該Entry裡包含的value值。 
Object setValue(V value):設定該Entry裡包含的value值,並返回新設定的value值。

 

import java.util.*;
public class MapTest
{
    public static void main(String[] args)
    {
        Map map = new HashMap();
        // 成對放入多個key-value對
        map.put("瘋狂Java講義" , 109);
        map.put("瘋狂iOS講義" , 10); map.put("瘋狂Ajax講義" , 79); // 多次放入的key-value對中value可以重複 map.put("輕量級Java EE企業應用實戰" , 99); // 放入重複的key時,新的value會覆蓋原有的value // 如果新的value覆蓋了原有的value,該方法返回被覆蓋的value System.out.println(map.put("瘋狂iOS講義" , 99)); // 輸出10 System.out.println(map); // 輸出的Map集合包含4個key-value對 // 判斷是否包含指定key System.out.println("是否包含值為 瘋狂iOS講義 key:" + map.containsKey("瘋狂iOS講義")); // 輸出true // 判斷是否包含指定value System.out.println("是否包含值為 99 value:" + map.containsValue(99)); // 輸出true // 獲取Map集合的所有key組成的集合,通過遍歷key來實現遍歷所有key-value對 for (Object key : map.keySet() ) { // map.get(key)方法獲取指定key對應的value System.out.println(key + "-->" + map.get(key)); } map.remove("瘋狂Ajax講義"); // 根據key來刪除key-value對。 System.out.println(map); // 輸出結果不再包含 瘋狂Ajax講義=79 的key-value對  } }

Java8 為Map新增的方法

Object compute(Object key,BiFunction remappingFunction); 
Object computeIfAbsent(Object key,Function mappingFunction); 
Object computeIfPresent(Object key,BiFunction remappingFunction); 
void forEach(BiConsumer action); 
Object getOrDefault(Object key,V defaultValue); 
Object merge(Object key,Object value,Bifunction remappingFunction); 
Object putIfAbsent(Object key,Object value); 
Object replace(Object key,Object value); 
boolean replace(K key,V oldValue,V newValue); 
replaceAll(BiFunction function);

public class MapTest2
{
    public static void main(String[] args)
    {
        Map map = new HashMap();
        // 成對放入多個key-value對
        map.put("瘋狂Java講義" , 109);
        map.put("瘋狂iOS講義" , 99);
        map.put("瘋狂Ajax講義" , 79); // 嘗試替換key為"瘋狂XML講義"的value,由於原Map中沒有對應的key, // 因此對Map沒有改變,不會新增新的key-value對 map.replace("瘋狂XML講義" , 66); System.out.println(map); // 使用原value與引數計算出來的結果覆蓋原有的value map.merge("瘋狂iOS講義" , 10 , (oldVal , param) -> (Integer)oldVal + (Integer)param); System.out.println(map); // "瘋狂iOS講義"的value增大了10 // 當key為"Java"對應的value為null(或不存在時),使用計算的結果作為新value map.computeIfAbsent("Java" , (key)->((String)key).length()); System.out.println(map); // map中添加了 Java=4 這組key-value對 // 當key為"Java"對應的value存在時,使用計算的結果作為新value map.computeIfPresent("Java", (key , value) -> (Integer)value * (Integer)value); System.out.println(map); // map中 Java=4 變成 Java=16  } }

Java 8改進的HashMap和Hashtable實現類

HashMap和Hashtable存在兩點典型區別 
  1.Hashtable是一個執行緒安全的Map實現,但HashMap是執行緒不安全的實現,所以HashMap比Hashtable的效能高一點。 
  2.Hashtable不允許使用null作為key和value,如果試圖把null值放Hashtable中,將會引發NullPointerException異常;但HashMap可以使用null作為key或value。 
  為了成功地在HashMap、Hashtable中儲存、獲取物件,用作key的物件必須實現hashCode()方法和equals()方法。

LinkedHashMap實現類

LinkedHashMap使用雙向連結串列來維護key-value對的次序。

public class LinkedHashMapTest
{
    public static void main(String[] args)
    {
        LinkedHashMap scores = new LinkedHashMap();
        scores.put("語文" , 80);
        scores.put("英文" , 82);
        scores.put("數學" , 76); // 呼叫forEach方法遍歷scores裡的所有key-value對 scores.forEach((key, value) -> System.out.println(key + "-->" + value)); } }

 

TreeMap

  TreeMap就是一個紅黑樹資料結構,每個key-value對即作為紅黑樹的一個節點。TreeMap也有兩種排序方法。 
   自然排序:TreeMap的所有key必須實現Comparable介面,而且所有的key應該是同一個類的物件,否則將會丟擲ClassCastException異常。 
   定製排序:建立TreeMap時,傳入一個Comparator物件,該物件負責對TreeMap中的所有key進行排序。採用定製排序時,不要求Map的key實現Comparable介面。 
   如果使用自定義類作為TreeMap的key,則重寫該類的equals()方法和comparaTo()方法時應保持一致的返回結果。

 

class R implements Comparable
{
    int count;
    public R(int count)
    {
        this.count = count;
    }
    public String toString()
    {
        return "R[count:" + count + "]"; } // 根據count來判斷兩個物件是否相等。 public boolean equals(Object obj) { if (this == obj) return true; if (obj != null && obj.getClass() == R.class) { R r = (R)obj; return r.count == this.count; } return false; } // 根據count屬性值來判斷兩個物件的大小。 public int compareTo(Object obj) { R r = (R)obj; return count > r.count ? 1 : count < r.count ? -1 : 0; } } public class TreeMapTest { public static void main(String[] args) { TreeMap tm = new TreeMap(); tm.put(new R(3) , "輕量級Java EE企業應用實戰"); tm.put(new R(-5) , "瘋狂Java講義"); tm.put(new R(9) , "瘋狂Android講義"); System.out.println(tm); // 返回該TreeMap的第一個Entry物件  System.out.println(tm.firstEntry()); // 返回該TreeMap的最後一個key值  System.out.println(tm.lastKey()); // 返回該TreeMap的比new R(2)大的最小key值。 System.out.println(tm.higherKey(new R(2))); // 返回該TreeMap的比new R(2)小的最大的key-value對。 System.out.println(tm.lowerEntry(new R(2))); // 返回該TreeMap的子TreeMap System.out.println(tm.subMap(new R(-1) , new R(4))); } }

WeakHashMap和IdentityHashMap

WeakHashMap與HashMap的用法基本相似,與HashMap的區別在於,HashMap的key保留了對實際物件的強引用,這意味著只要該HashMap物件不被銷燬,該HashMap的所有key所引用的物件就不會被垃圾回收,HashMap也不會自動刪除這些key所對應的key-value對;但WeakHashMap的key只保留了對實際物件的弱引用,這意味著如果WeakHashMap物件的key所引用的物件沒有被其他強引用變數所引用,則這些key所引用的物件可能被垃圾回收,WeakHashMap也可能自動刪除這些key所對應的key-value對。 
   在IdentityHashMap中,當且僅當兩個key嚴格相等(key1==key2)時,IdentityHashMap才認為兩個key相等;對於普通的HashMap而言,只要key1和key2通過equals()方法比較返回true,且它們的hashCode值相等即可。