1. 程式人生 > >HashMap和TreeMap存取null鍵和null值的情況

HashMap和TreeMap存取null鍵和null值的情況

1.HashMap支援null鍵和null值

JSE6.0描述:基於雜湊表的 Map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證對映的順序,特別是它不保證該順序恆久不變。 

import java.util.HashMap;

public class testHashMap {
	public static void main(String[] args) {
		HashMap<String, Integer> hs = new HashMap<String, Integer>();
		hs.put("一", 1);
		hs.put("二", 2);
		hs.put("三", null);
		hs.put(null, null);

		// 都可以存取null,所以不可以通過ge()返回值來判斷鍵是否為null
		System.out.println(hs.get("三"));
		System.out.println(hs.get(null));
	}
}

結果:

null
null

為什麼可以:HashMap不需要排序,get()方法不依賴於鍵

public V get(Object key) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (key==null) {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    return e.getValue();
            }
        } else {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    return e.getValue();
            }
        }
        return null;
    }

2.TreeMap不支援null鍵,但是支援null值

import java.util.TreeMap;

public class testTreeMap {
	public static void main(String[] args) {
		Map<String, Integer> ts = new TreeMap<>();
		ts.put("一", 1);
		ts.put("二", 2);
		ts.put("三", null);
		// ts.put(null, 4);
		System.out.println(ts.get("三"));
		// System.out.println(ts.get(null));
	}
}
結果:
null

去掉註釋結果:

Exception in thread "main" java.lang.NullPointerException
	at java.util.TreeMap.put(TreeMap.java:563)
	at shangjizuoye.testTreeMap.main(testTreeMap.java:11)

雖然可以通過自己構建比較器來實現存入null鍵但是get()方法不可用

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class testTreeMap {
	public static void main(String[] args) {
	       Map<String, Integer> ts = new TreeMap<>(new Comparator<String>() {
	            public int compare(String s1, String s2) {      // 這裡明確s1是要拿進來存的資料 s2是已經存進來的資料
	                if (s1 == null){
	                    return 1;
	            }
	                else {
	                    return s2.charAt(0) - s1.charAt(0);
	                }
	            }
	        });
	        ts.put("一", 1);
	        ts.put("二", 2);
	        ts.put(null, 3);
	        
	        System.out.println(ts.get("一"));
	        System.out.println(ts.get(null));
	}
}
結果:
1
null

用了我們自己的構造器

public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
    final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }
取得時候還是呼叫了我傳入的
Comparable

相等的時候傳出來值,但是這個設定的比較null結果為1不可能為0,所以就找不到返回空。

所以還是不要用TreeMap存null鍵的元素