Java Map 中的 key 和 value 能否为 null ?


#Java 笔记


类型 全路径 key是否允许null value是否允许null
HashMap java.util.HashMap 允许 允许
LinkedHashMap java.util.LinkedHashMap 允许 允许
ConcurrentHashMap java.util.concurrent.ConcurrentHashMap 不允许 不允许
ConcurrentSkipListMap java.util.concurrent.ConcurrentSkipListMap 不允许 不允许
Hashtable java.util.Hashtable 不允许 不允许
  • HashMap 、LinkedHashMap 的 key 和 value 都允许为 null。
  • ConcurrentHashMap、ConcurrentSkipListMap、Hashtable 的 key 和 value 都不允许为 null。

测试示例:

HashMap 示例

import java.util.HashMap;

public class Main {

    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();

        // key 和 value 都可以是 null
        map.put(null, null);
        System.out.println( map.get(null) );  // 输出 null

        // key 是 null,value 不是 null
        map.put(null, "v1");
        System.out.println( map.get(null) );  // 输出 v1

        // key 是 null,value 不是 null
        map.put("k2", null);
        System.out.println( map.get("k2") );  // 输出 null

        // key 不存在时,get 方法返回 null
        System.out.println( map.get("k3") );  // 输出 null
    }

}

ConcurrentHashMap 示例

ConcurrentHashMap 中 key 和 value 都不能是 null,否则会报空指针异常(NullPointerException)。

import java.util.concurrent.ConcurrentHashMap;

public class Main {

    public static void main(String[] args) {
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

        try {
            map.put(null, null);            // 报错 java.lang.NullPointerException
        } catch (NullPointerException ex) {
            System.out.println("空指针异常");
        }

        try {
            map.put(null, "v1");            // 报错 java.lang.NullPointerException
        } catch (NullPointerException ex) {
            System.out.println("空指针异常");
        }

        try {
            map.put("k2", null);            // 报错 java.lang.NullPointerException
        } catch (NullPointerException ex) {
            System.out.println("空指针异常");
        }

        try {
            System.out.println( map.get(null) );  // 报错 java.lang.NullPointerException
        } catch (NullPointerException ex) {
            System.out.println("空指针异常");
        }

        System.out.println( map.get("k3") );  // 输出 null

    }

}

如果需要是 null ,怎么做?

使用一个特定的类来包装 key、 value,比如 Optional 类 。示例:

import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

public class Main {

    public static void main(String[] args) {
        ConcurrentHashMap<Optional<String>, Optional<String>> map = new ConcurrentHashMap<>();

        map.put(Optional.ofNullable(null), Optional.ofNullable(null));
        map.put(Optional.ofNullable(null), Optional.ofNullable("v1"));
        map.put(Optional.ofNullable("k2"), Optional.ofNullable(null));

        System.out.println( map.get(Optional.ofNullable(null)) );  // 输出 Optional[v1]
        System.out.println( map.get(Optional.ofNullable("k2")) );  // 输出 Optional.empty
        System.out.println( map.get("k2") );  // 输出 null
    }

}


( 本文完 )