Map Implementations

Map实现分为通用实现,特殊实现和并发实现。

通用 Map 实现

三种通用的Map实现是HashMapTreeMapLinkedHashMap。如果需要SortedMap操作或键排序的Collection -view 迭代,请使用TreeMap;如果要最大速度并且不关心迭代 Sequences,请使用HashMap;如果您想要接近HashMap的性能和插入 Sequences 迭代,请使用LinkedHashMap。在这方面,Map的情况类似于Set。同样,Set Implementations部分中的所有其他内容也适用于Map实现。

LinkedHashMap提供了LinkedHashSet不具备的两个功能。创建LinkedHashMap时,您可以基于键访问而不是插入对其进行排序。换句话说,仅查找与键关联的值会将键带到 Map 的末尾。同样,LinkedHashMap提供了removeEldestEntry方法,当将新 Map 添加到 Map 时,可以重写此方法以强加自动删除陈旧 Map 的策略。这使得实现自定义缓存非常容易。

例如,此覆盖将使 Map 最多可以扩展到 100 个条目,然后每次添加新条目时都会删除最旧的条目,从而保持 100 个条 Object 稳定状态。

private static final int MAX_ENTRIES = 100;

protected boolean removeEldestEntry(Map.Entry eldest) {
    return size() > MAX_ENTRIES;
}

专用 Map 实现

有三种特殊用途的 Map 实现-EnumMapWeakHashMapIdentityHashMapEnumMap在内部实现为array,是用于枚举键的高性能Map实现。此实现将Mapinterface的丰富性和安全性与接近数组的速度结合在一起。如果要将枚举 Map 到值,则应始终使用EnumMap优先于数组。

WeakHashMapMapinterface的实现,该interface仅存储对其键的弱引用。仅存储弱引用可以在不再在WeakHashMap之外引用其键时对键值对进行垃圾回收。此类提供了利用弱引用功能的最简单方法。这对于实现“类似注册表的”数据结构很有用,在该结构中,当任何线程都无法再访问其键时,条 Object 实用性就会消失。

IdentityHashMap是基于哈希表的基于身份的Map实现。此类对于保留拓扑的对象图转换(例如序列化或深度复制)很有用。要执行这样的转换,您需要维护一个基于身份的“节点表”,以跟踪已经看到了哪些对象。基于身份的 Map 还用于在动态调试器和类似系统中维护对象到元信息的 Map。最后,基于身份的 Map 在阻止“欺骗攻击”中很有用,因为“ IdentityHashMap”从不在其键上调用“ equals”方法,这是故意使equals方法不正确的结果。此实现的另一个好处是它速度很快。

并发 Map 实现

java.util.concurrent软件包包含ConcurrentMapinterface,该interface使用原子putIfAbsentremovereplace方法扩展Map以及该interface的ConcurrentHashMap实现。

ConcurrentHashMap是由哈希表支持的高度并发的高性能实现。该实现在执行检索时不会阻塞,并允许 Client 端选择用于更新的并发级别。它旨在替代Hashtable:除了实现ConcurrentMap之外,它还支持Hashtable特有的所有传统方法。同样,如果您不需要旧版操作,请小心使用ConcurrentMapinterface对其进行操作。