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键的元素





原文地址:https://www.cnblogs.com/wei1/p/9582096.html