Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。注意,如果在映射中重新插入 键,则插入顺序不受影响。(如果在调用m.put(k, v) 前 m.containsKey(k) 返回了 true,则调用时会将键 k 重新插入到映射 m 中。)
提供特殊的构造方法
来创建链接哈希映射,该哈希映射的迭代顺序就是最后访问其条目的顺序,从近期访问最少到近期访问最多的顺序(访问顺序)。这种映射很适合构建 LRU 缓存。
由于增加了维护链接列表的开支,其性能很可能比 HashMap 稍逊一筹,不过这一点例外:LinkedHashMap 的 collection 视图迭代所需时间与映射的大小 成比例。HashMap 迭代时间很可能开支较大,因为它所需要的时间与其容量 成比例。
链接的哈希映射具有两个影响其性能的参数:初始容量和加载因子。它们的定义与 HashMap 极其相似。要注意,为初始容量选择非常高的值对此类的影响比对HashMap 要小,因为此类的迭代时间不受容量的影响。
此实现不是同步的。
Map m = Collections.synchronizedMap(new LinkedHashMap(...));在按插入顺序链接的哈希映射中,仅更改与映射中已包含键关联的值不是结构修改。 在按访问顺序链接的哈希映射中,仅利用 get 查询映射不是结构修改。
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
继承HashMap类,实现map接口。
public LinkedHashMap() { super(); accessOrder = false; }由构造方法可知,其调用父类构造方法。
<pre name="code" class="java">void init() { header = new Entry<K,V>(-1, null, null, null); header.before = header.after = header; }
public boolean containsValue(Object value) { // Overridden to take advantage of faster iterator if (value==null) { for (Entry e = header.after; e != header; e = e.after) if (e.value==null) return true; } else { for (Entry e = header.after; e != header; e = e.after) if (value.equals(e.value)) return true; } return false; }通过链表的形式来访问,是否包含某个元素。
public void clear() { super.clear(); header.before = header.after = header; }调用父类的clear方法,同时修改链表结构。