Java集合之Map

459 阅读2分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

Map 是 Java 中常用集合之一,其重点实现类包括 HashMap、LinkedHashMap、TreeMap 和 Hashtable

注意:Map 是集合,但并不属于 Collection。

Java集合-Map.png

HashMap

HashMap 的底层采用数组 + 链表 / 红黑树(JDK 1.8)。HashMap 键的唯一性,是通过 hashcode 来保证的,因此,若其键为实体,则需要重写 equals() 和 hashcode()。

HashMap底层.png

LinkedHashMap

LinkedHashMap 是 HashMap 的一种特殊形式,其 Entry 加入了 before 和 after,从而使其底层变为了数组 + 双向链表的形式。双向链表记录了整个 table 的顺序,因此 LinkedHashMap 是有序的

static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

HashMap 和 LinkedHashMap 的结构示意图如下:

LinkedHashMap结构.png

Hashtable

Hashtable 是线程安全的,但因为性能问题,已被废弃。在多线程环境中,可以使用 Collections.synchronizedMap 或者 ConcurrentHashMap,前者加锁的地方更多,因此后者的性能更好。

其它 Map

  1. IdentityHashMap 允许键值为 null,不能保证插入遍历的顺序一致。其特殊的地方是用 == 来比较 key 是否相等,而不是 equals。
  2. WeakHashMap 的 key 报错了实际对象的弱引用,因此键值对会随着实际对象的回收而自动删除,不太常用。
  3. TreeM 是非线程安全的,基于红黑树实现,因为该树总处于平衡状态,因此没有调优选项。不过可以通过重写比较器来实现自定义排序。

总结

keyvalue容量扩容有序性父类hashcode说明
HashMap允许 null允许 null162n无序AbstractMap重新计算非线程安全
LinkedHashMap允许 null允许 null162n有序AbstractMap重新计算非线程安全
TreeMap不允许 null允许 null162n自然排序AbstractMap重新计算非线程安全
ConcurrentHashMap不允许 null不允许 null162n无序AbstractMap重新计算锁分段技术
Hashtable不允许 null不允许 null112n+1无序Dictionary直接使用线程安全