通用Map实现
Map
的三个通用实现是 HashMap
, TreeMap
和 LinkedHashMap
。如果需要SortedMap
操作或键顺序Collection
视图迭代,请使用TreeMap
; 如果您想要最大速度并且不关心迭代顺序,请使用HashMap
; 如果要获得接近HashMap
性能和插入顺序的迭代,请使用LinkedHashMap
。在这方面,情况Map
类似于Set
。同样,“Set实现”部分中的所有其他内容也适用于Map
实现。LinkedHashMap
提供了LinkedHashSet
不能使用的两种功能。创建LinkedHashMap
时,您可以基于密钥访问权限而不是插入顺序进行排序。换句话说,仅查找与键关联的值会将键带到Map的末尾。另外,LinkedHashMap
提供了removeEldestEntry
方法,当将新映射添加到Map时,可以重写该方法以强加自动删除陈旧映射的策略。这使得实现自定义缓存非常容易。
例如,此覆盖将使Map最多可以扩展到100个条目,然后每次添加新条目时都会删除最旧的条目,从而保持100个条目的稳定状态。
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
特殊Map实现
有三个专用Map实现—— EnumMap
, WeakHashMap
和 IdentityHashMap
。EnumMap
在内部以array
形式实现,是一种用于枚举键的高性能Map
实现。此实现将Map
接口的丰富性和安全性与接近数组的速度结合在一起。如果要将枚举映射到值,则应始终使用EnumMap
优于数组。WeakHashMap
是Map
接口的实现,该接口仅存储对其键的弱引用。当不再在WeakHashMap
外部引用键值对时,仅存储弱引用将允许对键值对进行垃圾回收。此类提供了利用弱引用功能的最简单方法。这对于实现“类似注册表”的数据结构很有用,在该结构中,当任何线程都无法再访问其键时,条目的实用性就会消失。IdentityHashMap
是基于哈希表的基于身份的Map
实现。此类对于保留拓扑的对象图转换(例如序列化或深度复制)很有用。要执行这样的转换,您需要维护一个基于身份的“节点表”,以跟踪已经看到了哪些对象。基于身份的映射还用于在动态调试器和类似系统中维护对象到元信息的映射。最后,基于身份的映射在阻止“欺骗攻击”中很有用,这是故意不正当的equals
方法的结果,因为IdentityHashMap
从未在其键上调用equals
方法。此实现的另一个好处是它速度很快。
并发Map实现
java.util.concurrent
包包含ConcurrentMap
接口,该接口扩展了Map
,使用原子操作putIfAbsent
,remove
和replace
方法,以及该接口的实现ConcurrentHashMap
。ConcurrentHashMap
是由哈希表支持的高度并发,高性能的实现。此实现在执行检索时不会阻塞,并允许客户端选择用于更新的并发级别。它旨在替代Hashtable
:除了实现ConcurrentMap
之外,它还支持Hashtable
所有特有的传统方法。同样,如果您不需要旧版操作,请小心使用ConcurrentMap
接口进行操作。