模块 java.base
 java.util

类 LinkedHashMap<K,V>

java.lang.Object
java.util.AbstractMap <K,V>
java.util.HashMap <K,V>
java.util.LinkedHashMap<K,V>
类型参数:
K - 此map维护的键类型
V - 映射值的类型
所有已实现的接口:
Serializable , Cloneable , Map<K,V>

public class LinkedHashMap<K,V> extends HashMap <K,V> implements Map <K,V>

Map 接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与 HashMap 的不同之处在于它维护一个贯穿其所有条目的双向链表。此链表定义了迭代顺序,通常是将键插入map的顺序(插入顺序).请注意,如果键是重新插入进入map。 (如果调用 m.put(k, v),而 m.containsKey(k) 将在调用前立即返回 true,则将键 k 重新插入map m。)

此实现使其客户免受 HashMap (和 Hashtable )提供的未指定的、通常混乱的排序,而不会导致与 TreeMap 相关的成本增加。它可用于生成与原始map具有相同顺序的map副本,而不管原始map的实现如何:


   void foo(Map<String, Integer> m) {
     Map<String, Integer> copy = new LinkedHashMap<>(m);
     ...
   }
  
如果模块在输入上获取map,复制它,然后返回其顺序由副本的顺序确定的结果,则此技术特别有用。 (客户通常喜欢按照物品呈现的相同顺序退货。)

提供了一个特殊的 constructor 来创建一个链接的hash map,其迭代顺序是其条目最后被访问的顺序,从最近最少访问到最近访问(访问顺序).这种map非常适合构建 LRU 缓存。调用 putputIfAbsentgetgetOrDefaultcomputecomputeIfAbsentcomputeIfPresentmerge 方法会导致对相应条目的访问(假设它在调用完成后存在)。如果值被替换,replace 方法只会导致访问条目。 putAll 方法为指定map中的每个映射生成一个条目访问,按照指定map的条目集迭代器提供键值映射的顺序。没有其他方法生成条目访问。特别是,对集合视图的操作not影响支持map的迭代顺序。

可以重写 removeEldestEntry(Map.Entry) 方法,以在将新映射添加到map时强制执行自动删除陈旧映射的策略。

此类提供所有可选的 Map 操作,并允许空元素。与 HashMap 一样,它为基本操作(addcontainsremove)提供恒定时间性能,假设散列函数将元素适当地分散在桶中。由于维护链接列表的额外费用,性能可能略低于 HashMap,但有一个例外:迭代 LinkedHashMap 的集合视图需要的时间与size的map,无论其容量。对 HashMap 的迭代可能会更昂贵,需要与其对应的时间capacity.

链接hash map有两个影响其性能的参数:初始容量负载系数.它们的定义与 HashMap 完全相同。但是请注意,为此类选择过高的初始容量值的惩罚没有 HashMap 严重,因为此类的迭代时间不受容量的影响。

请注意,此实现不是同步的。 如果多个线程同时访问链接的hash map,并且至少有一个线程在结构上修改了map,则它must 将在外部同步。这通常是通过同步某些自然封装map的对象来实现的。如果不存在这样的对象,则应使用 Collections.synchronizedMap 方法“包装”map。这最好在创建时完成,以防止意外的不同步访问map:

  Map m = Collections.synchronizedMap(new LinkedHashMap(...));
结构修改是添加或删除一个或多个映射的任何操作,或者在访问顺序链接hash map的情况下,影响迭代顺序。在按插入顺序链接的hash map中,仅更改与已包含在map中的键关联的值不是结构修改。 In access-ordered linked hash maps, merely querying the map with get is a structural modification. )

由此类的所有集合视图方法返回的集合的iterator方法返回的迭代器是fail-fast:如果在创建迭代器后的任何时间以任何方式对map进行结构修改,除了通过迭代器自己的remove方法,迭代器会抛出一个 ConcurrentModificationException 。因此,面对并发修改,迭代器会快速干净地失败,而不是冒着在未来不确定的时间出现任意的、不确定的行为的风险。

请注意,无法保证迭代器的快速失败行为,因为一般来说,在存在非同步并发修改的情况下不可能做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。

该类所有集合视图方法返回的集合的spliterator方法返回的spliterator为late-bindingfail-fast,另外报告Spliterator.ORDERED

此类是 Java 集合框架 的成员。

实现注意事项:
由该类的所有集合视图方法返回的集合的 spliterator 方法返回的拆分器是从相应集合的迭代器创建的。
自从:
1.4
参见:
  • 构造方法详细信息

    • LinkedHashMap

      public LinkedHashMap(int initialCapacity, float loadFactor)
      构造一个具有指定初始容量和加载因子的空插入顺序 LinkedHashMap 实例。
      API 注意:
      要创建初始容量可容纳预期映射数量的 LinkedHashMap,请使用 newLinkedHashMap
      参数:
      initialCapacity——初始容量
      loadFactor - 负载系数
      抛出:
      IllegalArgumentException - 如果初始容量为负或负载因子为非正
    • LinkedHashMap

      public LinkedHashMap(int initialCapacity)
      构造具有指定初始容量和默认加载因子 (0.75) 的空插入顺序 LinkedHashMap 实例。
      API 注意:
      要创建初始容量可容纳预期映射数量的 LinkedHashMap,请使用 newLinkedHashMap
      参数:
      initialCapacity——初始容量
      抛出:
      IllegalArgumentException - 如果初始容量为负
    • LinkedHashMap

      public LinkedHashMap()
      构造具有默认初始容量 (16) 和加载因子 (0.75) 的空插入顺序 LinkedHashMap 实例。
    • LinkedHashMap

      public LinkedHashMap(Map <? extends K ,? extends V > m)
      构造一个插入顺序的 LinkedHashMap 实例,其映射与指定map相同。 LinkedHashMap 实例是使用默认加载因子 (0.75) 和足以容纳指定map中的映射的初始容量创建的。
      参数:
      m - 其映射要放置在此map中的map
      抛出:
      NullPointerException - 如果指定的map为空
    • LinkedHashMap

      public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
      构造一个具有指定初始容量、负载因子和排序模式的空 LinkedHashMap 实例。
      参数:
      initialCapacity——初始容量
      loadFactor - 负载系数
      accessOrder - 排序模式 - true 用于访问顺序,false 用于插入顺序
      抛出:
      IllegalArgumentException - 如果初始容量为负或负载因子为非正
  • 方法详情

    • containsValue

      public boolean containsValue(Object  value)
      如果此map将一个或多个键映射到指定值,则返回 true
      指定者:
      containsValue 在接口 Map<K,V>
      重写:
      containsValue 在类 HashMap<K,V>
      参数:
      value - 要测试其在此map中是否存在的值
      返回:
      true 如果此map将一个或多个键映射到指定值
    • get

      public V  get(Object  key)
      返回指定键映射到的值,如果此map不包含键的映射,则返回 null

      更正式地说,如果此map包含从键 k 到值 v 的映射,使得 (key==null ? k==null : key.equals(k)) ,则此方法返回 v ;否则返回 null 。 (最多可以有一个这样的映射。)

      null 的返回值不一定指示map不包含键的映射;map也可能将密钥显式映射到 nullcontainsKey 操作可用于区分这两种情况。

      指定者:
      get 在接口 Map<K,V>
      重写:
      get 在类 HashMap<K,V>
      参数:
      key - 要返回其关联值的键
      返回:
      指定键映射到的值,如果此map不包含键的映射,则返回 null
      参见:
    • clear

      public void clear()
      从此map中删除所有映射。此调用返回后map将为空。
      指定者:
      clear 在接口 Map<K,V>
      重写:
      clear 在类 HashMap<K,V>
    • removeEldestEntry

      protected boolean removeEldestEntry(Map.Entry <K ,V > eldest)
      如果此map应删除其最旧的条目,则返回 true。在向map中插入新条目后,putputAll 会调用此方法。它为实现者提供了在每次添加新条目时删除最老条目的机会。如果map表示缓存,这将很有用:它允许映射通过删除陈旧条目来减少内存消耗。

      示例使用:此重写将允许map增长到 100 个条目,然后在每次添加新条目时删除最旧的条目,保持 100 个条目的稳定状态。

         private static final int MAX_ENTRIES = 100;
      
         protected boolean removeEldestEntry(Map.Entry eldest) {
          return size() > MAX_ENTRIES;
         }
       

      此方法通常不会以任何方式修改map,而是允许map按照其返回值的指示修改自身。它允许此方法直接修改map,但如果这样做,它必须返回 false(表示map不应尝试任何进一步的修改)。在此方法中修改map后返回 true 的效果未指定。

      此实现仅返回 false(因此此贴图就像普通map一样 - 永远不会删除最老的元素)。

      参数:
      eldest - map中最近最少插入的条目,或者如果这是访问顺序映射,则为最近最少访问的条目。这是将被删除的条目,如果此方法返回 true 。如果在 putputAll 调用导致此调用之前映射为空,则这将是刚刚插入的条目;换句话说,如果map包含单个条目,则最老的条目也是最新的。
      返回:
      true 是否应从map中删除最老的条目; false是否应该保留。
    • keySet

      public Set <K > keySet()
      返回此map中包含的键的 Set 视图。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map(除了通过迭代器自己的 remove 操作),迭代的结果是不确定的。该集合支持元素删除,即通过 Iterator.removeSet.removeremoveAllretainAllclear 操作从map中删除相应的映射。它不支持 addaddAll 操作。它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。
      指定者:
      keySet 在接口 Map<K,V>
      重写:
      keySet 在类 HashMap<K,V>
      返回:
      此map中包含的键的集合视图
    • values

      public Collection <V > values()
      返回此map中包含的值的 Collection 视图。集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map(除了通过迭代器自己的 remove 操作),迭代的结果是不确定的。该集合支持元素删除,即通过 Iterator.removeCollection.removeremoveAllretainAllclear 操作从map中删除相应的映射。它不支持 addaddAll 操作。它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。
      指定者:
      values 在接口 Map<K,V>
      重写:
      values 在类 HashMap<K,V>
      返回:
      此map中包含的值的视图
    • entrySet

      public Set <Map.Entry <K ,V >> entrySet()
      返回此map中包含的映射的 Set 视图。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时映射被修改(除了通过迭代器自己的 remove 操作,或通过迭代器返回的映射条目上的 setValue 操作),迭代的结果是未定义的。该集合支持元素移除,即通过 Iterator.removeSet.removeremoveAllretainAllclear 操作从map中移除相应的映射。它不支持 addaddAll 操作。它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。
      指定者:
      entrySet 在接口 Map<K,V>
      重写:
      entrySet 在类 HashMap<K,V>
      返回:
      此map中包含的映射的集合视图
    • newLinkedHashMap

      public static <K, V> LinkedHashMap <K,V> newLinkedHashMap(int numMappings)
      创建一个适合预期映射数量的新的、空的、插入顺序的 LinkedHashMap。返回的map使用默认的加载因子 0.75,它的初始容量通常足够大,因此可以在不调整map大小的情况下添加预期数量的映射。
      类型参数:
      K - 新map维护的键类型
      V - 映射值的类型
      参数:
      numMappings - 预期的映射数
      返回:
      新创建的map
      抛出:
      IllegalArgumentException - 如果 numMappings 为负
      自从:
      19