阅读(1134) (0)

鸿蒙OS LinkedHashMap

2022-06-16 16:25:09 更新

LinkedHashMap

java.lang.Object

|---java.util.AbstractMap<K,V&

|---|---java.util.HashMap<K,V&

|---|---|---java.util.LinkedHashMap<K,V&

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

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

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

     void foo(Map m) {
         Map copy = new LinkedHashMap(m);
         ...
     }

如果模块在输入上获取映射,复制它,然后返回其顺序由副本确定的结果,则此技术特别有用。 (客户通常喜欢以与呈现相同的顺序返回物品。)

提供了一个特殊的构造函数来创建一个链接哈希映射,其迭代顺序是其条目最后一次访问的顺序,从最近最少访问到最近访问(访问顺序)。 这种映射非常适合构建 LRU 缓存。 调用 put、putIfAbsent、get、getOrDefault、compute、computeIfAbsent、computeIfPresent 或 merge 方法会导致对相应条目的访问(假设它在调用完成后存在)。 如果值被替换,replace 方法只会导致对条目的访问。 putAll 方法为指定映射中的每个映射生成一个条目访问,按照指定映射的条目集迭代器提供键值映射的顺序。 没有其他方法生成条目访问。 特别是,collection-views 上的操作不会影响 backing map 的迭代顺序。

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

此类提供所有可选的 Map 操作,并允许 null 元素。 与 HashMap 一样,它为基本操作(添加、包含和删除)提供恒定时间性能,假设哈希函数在桶中正确地分散元素。 由于维护链表的额外费用,性能可能略低于 HashMap,但有一个例外:迭代 LinkedHashMap 的集合视图所需的时间与映射的大小成正比,而不管其容量如何 . HashMap 的迭代可能更昂贵,需要的时间与其容量成正比。

链接哈希图有两个影响其性能的参数:初始容量和负载因子。 它们的定义与 HashMap 一样。 但是请注意,对于此类而言,为初始容量选择过高值的惩罚不如 HashMap 严重,因为此类的迭代时间不受容量的影响。

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

   Map m = Collections.synchronizedMap(new LinkedHashMap(...));

结构修改是添加或删除一个或多个映射的任何操作,或者在访问排序的链接哈希映射的情况下,影响迭代顺序。 在插入排序的链接哈希映射中,仅更改与映射中已包含的键关联的值不是结构修改。 在按访问顺序链接的哈希映射中,仅使用 get 查询映射是一种结构修改。 )

由此类的所有集合视图方法返回的集合的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对映射进行结构修改,除了通过迭代器自己的 remove 方法之外的任何方式, 迭代器将抛出 ConcurrentModificationException。 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。

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

此类的所有集合视图方法返回的集合的 spliterator 方法返回的拆分器是后期绑定的、快速失败的,并且另外报告 Spliterator#ORDERED。

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

嵌套类摘要

从类 java.util.AbstractMap 继承的嵌套类/接口
AbstractMap.SimpleEntryK,V, AbstractMap.SimpleImmutableEntryK,V
从接口 java.util.Map 继承的嵌套类/接口
Map.EntryK,V

构造函数摘要

构造函数 描述
LinkedHashMap() 构造一个具有默认初始容量 (16) 和加载因子 (0.75) 的空插入排序 LinkedHashMap 实例。
LinkedHashMap(int initialCapacity) 构造一个具有指定初始容量和默认加载因子 (0.75) 的空插入排序 LinkedHashMap 实例。
LinkedHashMap(int initialCapacity, float loadFactor) 构造一个具有指定初始容量和负载因子的空插入排序 LinkedHashMap 实例。
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) 构造一个具有指定初始容量、加载因子和排序模式的空 LinkedHashMap 实例。
LinkedHashMap(Map<? extends K,? extends V> m) 构造一个插入顺序的 LinkedHashMap 实例,其映射与指定的映射相同。

方法总结

修饰符和类型 方法 描述
void clear() 从此 map 中删除所有映射。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。
SetMap.EntryK,V entrySet() 返回此映射中包含的映射的 Set 视图。
void forEach(BiConsumer<? super K,? super V> action) 对该映射中的每个条目执行给定的操作,直到处理完所有条目或该操作引发异常。
V get(Object key) 返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null。
V getOrDefault(Object key, V defaultValue) 返回指定键映射到的值,如果此映射不包含该键的映射,则返回 defaultValue。
SetK keySet() 返回此映射中包含的键的 Set 视图。
protected boolean removeEldestEntry(Map.EntryK,V eldest) 如果此映射应删除其最旧的条目,则返回 true。
void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都已处理或该函数引发异常。
CollectionV values() 返回此映射中包含的值的集合视图。
从类 java.util.AbstractMap 继承的方法
equals, hashCode, toString
从类 java.util.HashMap 继承的方法
clone, compute, computeIfAbsent, computeIfPresent, containsKey, isEmpty, merge, put, putAll, putIfAbsent, remove, remove, replace, replace, size
从接口 java.util.Map 继承的方法
compute, computeIfAbsent, computeIfPresent, containsKey, equals, hashCode, isEmpty, merge, put, putAll, putIfAbsent, remove, remove, replace, replace, size
从类 java.lang.Object 继承的方法
finalize, getClass, notify, notifyAll, wait, wait, wait

构造函数详细信息

LinkedHashMap

public LinkedHashMap(int initialCapacity, float loadFactor)

构造一个具有指定初始容量和负载因子的空插入排序 LinkedHashMap 实例。

参数:

参数名称 参数描述
initialCapacity 初始容量
loadFactor 负载系数

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果初始容量为负或负载因子为非正

LinkedHashMap

public LinkedHashMap(int initialCapacity)

构造一个具有指定初始容量和默认加载因子 (0.75) 的空插入排序 LinkedHashMap 实例。

参数:

参数名称 参数描述
initialCapacity 初始容量

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果初始容量为负

LinkedHashMap

public LinkedHashMap()

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

LinkedHashMap

public LinkedHashMap(Map<? extends K,? extends V> m)

构造一个插入顺序的 LinkedHashMap 实例,其映射与指定的映射相同。 LinkedHashMap 实例是使用默认加载因子 (0.75) 和足以在指定映射中保存映射的初始容量创建的。

参数:

参数名称 参数描述
m 其映射将放置在此 map 中的 map

Throws:

Throw名称 Throw描述
NullPointerException 如果指定的 map 为空

LinkedHashMap

public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)

构造一个具有指定初始容量、加载因子和排序模式的空 LinkedHashMap 实例。

参数:

参数名称 参数描述
initialCapacity 初始容量
loadFactor 负载系数
accessOrder 排序模式 - 访问顺序为 true,插入顺序为 false

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果初始容量为负或负载因子为非正

方法详情

containsValue

public boolean containsValue(Object value)

如果此映射将一个或多个键映射到指定值,则返回 true。

指定者:

接口 MapK,V 中的 containsValue

覆盖:

HashMapK,V 类中的 containsValue

参数:

参数名称 参数描述
value 要测试其在此映射中的存在的值

返回:

如果此映射将一个或多个键映射到指定值,则为 true

get

public V get(Object key)

返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null。

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

返回值为 null 并不一定表示该映射不包含该键的映射; 映射也可能将键显式映射为空。 containsKey 操作可用于区分这两种情况。

指定者:

进入接口 MapK,V

覆盖:

进入类 HashMapK,V

参数:

参数名称 参数描述
key 要返回其关联值的键

返回:

指定键映射到的值,如果此映射不包含该键的映射,则为 null

getOrDefault

public V getOrDefault(Object key, V defaultValue)

返回指定键映射到的值,如果此映射不包含该键的映射,则返回 defaultValue。

指定者:

接口 MapK,V 中的 getOrDefault

覆盖:

HashMapK,V 类中的 getOrDefault

参数:

参数名称 参数描述
key 要返回其关联值的键
defaultValue 键的默认映射

返回:

指定键映射到的值,如果此映射不包含该键的映射,则为 defaultValue

clear

public void clear()

从此 map 中删除所有映射。 此调用返回后,map 将为空。

指定者:

在界面 MapK,V 中清除

覆盖:

在类 HashMapK,V 中清除

removeEldestEntry

protected boolean removeEldestEntry(Map.EntryK,V eldest)

如果此映射应删除其最旧的条目,则返回 true。 在将新条目插入映射后,put 和 putAll 调用此方法。 它为实现者提供了在每次添加新条目时删除最旧条目的机会。 如果映射表示缓存,这很有用:它允许映射通过删除过时的条目来减少内存消耗。

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

     private static final int MAX_ENTRIES = 100;


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

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

此实现仅返回 false(因此此贴图的作用类似于法线贴图 - 永远不会删除最老的元素)。

参数:

参数名称 参数描述
eldest 映射中最近最少插入的条目,或者如果这是按访问排序的映射,则为最近最少访问的条目。 这是将被删除的条目,此方法返回 true。 如果在 put 或 putAll 调用导致此调用之前映射为空,则这将是刚刚插入的条目; 换句话说,如果映射包含单个条目,则最旧的条目也是最新的。

返回:

如果应该从 map 中删除最旧的条目,则为 true; 如果应该保留它,则为 false。

keySet

public SetK keySet()

返回此映射中包含的键的 Set 视图。 集合由 map 支持,因此对 map 的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。 该集合支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。 它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。

指定者:

接口 MapK,V 中的 keySet

覆盖:

HashMapK,V 类中的 keySet

返回:

此 map 中包含的键的集合视图

values

public CollectionV values()

返回此映射中包含的值的集合视图。 集合由 map 支持,因此对 map 的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。 该集合支持元素移除,即通过 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。 它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。

指定者:

接口 MapK,V 中的值

覆盖:

HashMapK,V 类中的值

返回:

此 map 中包含的值的视图

entrySet

public SetMap.EntryK,V entrySet()

返回此映射中包含的映射的 Set 视图。 集合由 map 支持,因此对 map 的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(除了通过迭代器自己的删除操作,或通过迭代器返回的映射条目上的 setValue 操作),则迭代的结果是未定义的。 该集合支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。 它的 Spliterator 通常提供更快的顺序性能,但比 HashMap 的并行性能差得多。

指定者:

接口 MapK,V 中的 entrySet

覆盖:

HashMapK,V 类中的 entrySet

返回:

此 map 中包含的映射的集合视图

forEach

public void forEach(BiConsumer<? super K,? super V> action)

从接口复制的描述:map

对该映射中的每个条目执行给定的操作,直到处理完所有条目或该操作引发异常。 除非实现类另有规定,否则按照条目集迭代的顺序执行动作(如果指定了迭代顺序)。动作抛出的异常将转发给调用者。

指定者:

接口 MapK,V 中的 forEach

覆盖:

HashMapK,V 类中的 forEach

参数:

参数名称 参数描述
action 为每个条目执行的操作

replaceAll

public void replaceAll(BiFunction<? super K,? super V,? extends V> function)

从接口复制的描述:map

将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都已处理或该函数引发异常。 函数抛出的异常被转发给调用者。

指定者:

接口 MapK,V 中的 replaceAll

覆盖:

类 HashMapK,V 中的 replaceAll

参数:

参数名称 参数描述
function 应用于每个条目的函数