【哪些Map支持key为null】

在Java的Map接口实现中,对于key为null的支持情况确实因实现而异。以下是一些常见的Map实现及其对null key的支持情况的总结:

支持key为null的Map实现

HashMap:
HashMap允许一个null key存在,并且可以有多个null value。当key为null时,HashMap会将其放置在内部数组的第一个位置(因为null的hashCode值为0)。需要注意的是,由于HashMap不保证映射的顺序,因此null key的插入位置虽然固定,但访问时不一定能按照插入顺序获取。
LinkedHashMap:
LinkedHashMap是HashMap的一个子类,它维护了一个双向链表来保持键值对的插入顺序或访问顺序。由于它继承自HashMap,因此同样支持null key。

IdentityHashMap:
IdentityHashMap使用==而不是equals()方法来比较键。这种比较方式允许null键的存在,因为null == null总是返回true。然而,IdentityHashMap主要用于需要基于对象身份(而非值)进行键比较的场景。
不支持key为null的Map实现
Hashtable:
Hashtable是线程安全的Map实现,它通过synchronized关键字来保证线程安全。由于历史原因和设计选择,Hashtable不允许任何null键或null值。如果尝试插入null键或null值,将抛出NullPointerException。
Properties:
Properties类继承自Hashtable,因此它同样不允许null键或null值。Properties类通常用于处理配置文件,如.properties文件。

ConcurrentHashMap:
ConcurrentHashMap是线程安全的并发哈希表,它不允许null键或null值。这是为了避免在多线程环境下出现二义性,特别是当使用containsKey()和get()方法时。如果尝试插入null键或null值,将抛出NullPointerException。
TreeMap:
TreeMap是基于红黑树实现的NavigableMap接口,它需要对键进行自然排序或通过提供的Comparator进行排序。由于null无法参与比较(会抛出NullPointerException),因此TreeMap不允许null键。
ConcurrentSkipListMap:
ConcurrentSkipListMap是另一个线程安全的Map实现,它基于跳表(Skip List)数据结构。与ConcurrentHashMap类似,它也不允许null键或null值。
总结
**HashMap、LinkedHashMap和IdentityHashMap**支持null键。
Hashtable、Properties、ConcurrentHashMap、TreeMap和ConcurrentSkipListMap**不支持null键**。
在选择Map实现时,应根据具体需求考虑是否允许null键,并选择合适的实现。如果应用程序需要线程安全的Map且不允许null键,则可以选择ConcurrentHashMap或ConcurrentSkipListMap。如果不需要线程安全且允许null键,则可以选择HashMap或LinkedHashMap。IdentityHashMap则适用于需要基于对象身份进行键比较的场景。