HashMap
java.lang.Object
|—java.util.AbstractMap<K,V&
|—|—java.util.HashMap<K,V&
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
Map 接口的基于哈希表的实现。 此实现提供所有可选的映射操作,并允许空值和空键。 (HashMap 类大致相当于 Hashtable,除了它是不同步的并且允许空值。)这个类不保证映射的顺序; 特别是,它不保证订单会随着时间的推移保持不变。
此实现为基本操作(get 和 put)提供恒定时间性能,假设哈希函数将元素正确地分散在桶中。 集合视图的迭代需要的时间与 HashMap 实例的“容量”(桶的数量)加上它的大小(键值映射的数量)成正比。 因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。
HashMap 的实例有两个影响其性能的参数:初始容量和负载因子。 容量是哈希表中的桶数,初始容量只是哈希表创建时的容量。 负载因子是哈希表在其容量自动增加之前允许达到的程度的度量。 当哈希表中的条目数超过负载因子和当前容量的乘积时,对哈希表进行重新哈希(即重建内部数据结构),使哈希表具有大约两倍的桶数。
作为一般规则,默认负载因子 (.75) 在时间和空间成本之间提供了良好的折衷。 较高的值会减少空间开销,但会增加查找成本(反映在 HashMap 类的大多数操作中,包括 get 和 put)。 在设置其初始容量时,应考虑映射中的预期条目数及其负载因子,以尽量减少重新哈希操作的次数。 如果初始容量大于最大条目数除以负载因子,则不会发生重新哈希操作。
如果要在 HashMap 实例中存储许多映射,则创建具有足够大容量的映射将比让它根据需要执行自动重新散列以增长表来更有效地存储映射。 请注意,使用具有相同 hashCode() 的多个键是降低任何哈希表性能的可靠方法。 为了改善影响,当键是 Comparable 时,此类可以使用键之间的比较顺序来帮助打破平局。
请注意,此实现不同步。 如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)这通常通过在自然封装映射的某个对象上同步来完成 . 如果不存在这样的对象,则应使用 Collections#synchronizedMap 方法“包装”地图。 这最好在创建时完成,以防止对地图的意外不同步访问:
Map m = Collections.synchronizedMap(new HashMap(...));
所有此类的“集合视图方法”返回的迭代器都是快速失败的:如果在创建迭代器后的任何时间对映射进行结构修改,除了通过迭代器自己的 remove 方法之外,迭代器将抛出 ConcurrentModificationException . 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。
请注意,不能保证迭代器的快速失败行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。 快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。 因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。
此类是 Java 集合框架的成员。
嵌套类摘要
从类 java.util.AbstractMap 继承的嵌套类/接口 |
---|
AbstractMap.SimpleEntryK,V, AbstractMap.SimpleImmutableEntryK,V |
从接口 java.util.Map 继承的嵌套类/接口 |
---|
Map.EntryK,V |
构造函数摘要
构造函数 | 描述 |
---|---|
HashMap() | 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。 |
HashMap(int initialCapacity) | 构造一个具有指定初始容量和默认加载因子 (0.75) 的空 HashMap。 |
HashMap(int initialCapacity, float loadFactor) | 构造一个具有指定初始容量和负载因子的空 HashMap。 |
HashMap(Map<? extends K,? extends V> m) | 构造一个与指定 Map 具有相同映射的新 HashMap。 |
方法总结
修饰符和类型 | 方法 | 描述 |
---|---|---|
void | clear() | 从此 map 中删除所有映射。 |
Object | clone() | 返回此 HashMap 实例的浅表副本:键和值本身没有被克隆。 |
V | compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为 null)。 |
V | computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | 如果指定的键尚未与值关联(或映射为 null),则尝试使用给定的映射函数计算其值并将其输入到此映射中,除非为 null。 |
V | computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 如果指定键的值存在且非空,则尝试在给定键及其当前映射值的情况下计算新映射。 |
boolean | containsKey(Object key) | 如果此映射包含指定键的映射,则返回 true。 |
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。 |
boolean | isEmpty() | 如果此映射不包含键值映射,则返回 true。 |
SetK | keySet() | 返回此映射中包含的键的 Set 视图。 |
V | merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | 如果指定的键尚未与值关联或与 null 关联,则将其与给定的非 null 值关联。 |
V | put(K key, V value) | 将指定的值与此映射中的指定键相关联。 |
void | putAll(Map<? extends K,? extends V> m) | 将所有映射从指定映射复制到此映射。 |
V | putIfAbsent(K key, V value) | 如果指定的键尚未与值关联(或映射到 null),则将其与给定值关联并返回 null,否则返回当前值。 |
V | remove(Object key) | 如果存在,则从此映射中删除指定键的映射。 |
boolean | remove(Object key, Object value) | 仅当当前映射到指定值时,才删除指定键的条目。 |
V | replace(K key, V value) | 仅当当前映射到某个值时才替换指定键的条目。 |
boolean | replace(K key, V oldValue, V newValue) | 仅当当前映射到指定值时才替换指定键的条目。 |
void | replaceAll(BiFunction<? super K,? super V,? extends V> function) | 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都已处理或该函数引发异常。 |
int | size() | 返回此映射中键值映射的数量。 |
CollectionV | values() | 返回此映射中包含的值的集合视图。 |
从类 java.util.AbstractMap 继承的方法 |
---|
equals, hashCode, toString |
从接口 java.util.Map 继承的方法 |
---|
equals, hashCode |
从类 java.lang.Object 继承的方法 |
---|
finalize, getClass, notify, notifyAll, wait, wait, wait |
构造函数详细信息
HashMap
public HashMap(int initialCapacity, float loadFactor)
构造一个具有指定初始容量和负载因子的空 HashMap。
参数:
参数名称 | 参数描述 |
---|---|
initialCapacity | 初始容量 |
loadFactor | 负载系数 |
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果初始容量为负或负载因子为非正 |
HashMap
public HashMap(int initialCapacity)
构造一个具有指定初始容量和默认加载因子 (0.75) 的空 HashMap。
参数:
参数名称 | 参数描述 |
---|---|
initialCapacity | 初始容量。 |
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果初始容量为负。 |
HashMap
public HashMap()
构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
HashMap
public HashMap(Map<? extends K,? extends V> m)
构造一个与指定 Map 具有相同映射的新 HashMap。 HashMap 是使用默认加载因子 (0.75) 和足以容纳指定 Map 中的映射的初始容量创建的。
参数:
参数名称 | 参数描述 |
---|---|
m | 其映射将放置在此 map 中的 map |
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的 map 为空 |
方法详情
size
public int size()
返回此映射中键值映射的数量。
指定者:
接口 MapK,V 中的大小
覆盖:
AbstractMapK,V 类中的大小
返回:
此映射中的键值映射的数量
isEmpty
public boolean isEmpty()
如果此映射不包含键值映射,则返回 true。
指定者:
接口 MapK,V 中的 isEmpty
覆盖:
AbstractMapK,V 类中的 isEmpty
返回:
如果此映射不包含键值映射,则为 true
get
public V get(Object key)
返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null。
更正式地说,如果此映射包含从键 k 到值 v 的映射,使得 (key==null ? k==null : key.equals(k)),则此方法返回 v; 否则返回null。 (最多可以有一个这样的映射。)
返回值为 null 并不一定表示该映射不包含该键的映射; 映射也可能将键显式映射为空。 containsKey 操作可用于区分这两种情况。
指定者:
进入接口 MapK,V
覆盖:
进入类 AbstractMapK,V
参数:
参数名称 | 参数描述 |
---|---|
key | 要返回其关联值的键 |
返回:
指定键映射到的值,如果此映射不包含该键的映射,则为 null
containsKey
public boolean containsKey(Object key)
如果此映射包含指定键的映射,则返回 true。
指定者:
containsKey 在接口 MapK,V
覆盖:
类 AbstractMapK,V 中的 containsKey
参数:
参数名称 | 参数描述 |
---|---|
key | 要测试在此映射中是否存在的键 |
返回:
如果此映射包含指定键的映射,则为 true。
put
public V put(K key, V value)
将指定的值与此映射中的指定键相关联。 如果映射先前包含键的映射,则替换旧值。
指定者:
放入接口 MapK,V
覆盖:
放入类 AbstractMapK,V
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
value | 与指定键关联的值 |
返回:
与 key 关联的前一个值,如果没有 key 映射,则返回 null。 (返回 null 还可以指示映射先前将 null 与 key 关联。)
putAll
public void putAll(Map<? extends K,? extends V> m)
将所有映射从指定映射复制到此映射。 这些映射将替换此映射对当前指定映射中的任何键的任何映射。
指定者:
putAll在接口MapK,V中
覆盖:
putAll 在类 AbstractMapK,V
参数:
参数名称 | 参数描述 |
---|---|
m | 要存储在此 map 中的映射 |
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的 map 为空 |
remove
public V remove(Object key)
如果存在,则从此映射中删除指定键的映射。
指定者:
在接口 MapK,V 中移除
覆盖:
在类 AbstractMapK,V 中删除
参数:
参数名称 | 参数描述 |
---|---|
key | 要从映射中删除其映射的键 |
返回:
与 key 关联的前一个值,如果没有 key 映射,则返回 null。 (返回 null 还可以指示映射先前将 null 与 key 关联。)
clear
public void clear()
从此 map 中删除所有映射。 此调用返回后,map 将为空。
指定者:
在界面 MapK,V 中清除
覆盖:
在类 AbstractMapK,V 中清除
containsValue
public boolean containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
指定者:
接口 MapK,V 中的 containsValue
覆盖:
类 AbstractMapK,V 中的 containsValue
参数:
参数名称 | 参数描述 |
---|---|
value | 要测试其在此映射中的存在的值 |
返回:
如果此映射将一个或多个键映射到指定值,则为 true
keySet
public SetK keySet()
返回此映射中包含的键的 Set 视图。 集合由 map 支持,因此对地图的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。 该集合支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。
指定者:
接口 MapK,V 中的 keySet
覆盖:
AbstractMapK,V 类中的 keySet
返回:
此 map 中包含的键的集合视图
values
public CollectionV values()
返回此映射中包含的值的集合视图。 集合由 map 支持,因此对地图的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。 该集合支持元素移除,即通过 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。
指定者:
接口 MapK,V 中的值
覆盖:
AbstractMapK,V 类中的值
返回:
此 map 中包含的值的视图
entrySet
public SetMap.EntryK,V entrySet()
返回此映射中包含的映射的 Set 视图。 集合由 map 支持,因此对地图的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作或通过迭代器返回的映射条目上的 setValue 操作除外),则迭代的结果是未定义的。 该集合支持元素移除,即通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 它不支持 add 或 addAll 操作。
指定者:
接口 MapK,V 中的 entrySet
指定者:
AbstractMapK,V 类中的 entrySet
返回:
此 map 中包含的映射的集合视图
getOrDefault
public V getOrDefault(Object key, V defaultValue)
从接口复制的描述:map
返回指定键映射到的值,如果此映射不包含该键的映射,则返回 defaultValue。
指定者:
接口 MapK,V 中的 getOrDefault
参数:
参数名称 | 参数描述 |
---|---|
key | 要返回其关联值的键 |
defaultValue | 键的默认映射 |
返回:
指定键映射到的值,如果此映射不包含该键的映射,则为 defaultValue
putIfAbsent
public V putIfAbsent(K key, V value)
从接口复制的描述:map
如果指定的键尚未与值关联(或映射到 null),则将其与给定值关联并返回 null,否则返回当前值。
指定者:
接口 MapK,V 中的 putIfAbsent
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
value | 与指定键关联的值 |
返回:
与指定键关联的前一个值,如果键没有映射,则返回 null。 (如果实现支持 null 值,则返回 null 还可以指示映射先前将 null 与键关联。)
remove
public boolean remove(Object key, Object value)
从接口复制的描述:map
仅当当前映射到指定值时,才删除指定键的条目。
指定者:
在接口 MapK,V 中移除
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
value | 预期与指定键关联的值 |
返回:
如果值已被删除,则为 true
replace
public boolean replace(K key, V oldValue, V newValue)
从接口复制的描述:map
仅当当前映射到指定值时才替换指定键的条目。
指定者:
在接口 MapK,V 中替换
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
oldValue | 预期与指定键关联的值 |
newValue | 与指定键关联的值 |
返回:
如果值被替换,则为 true
replace
public V replace(K key, V value)
从接口复制的描述:map
仅当当前映射到某个值时才替换指定键的条目。
指定者:
在接口 MapK,V 中替换
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
value | 与指定键关联的值 |
返回:
与指定键关联的前一个值,如果键没有映射,则返回 null。 (如果实现支持 null 值,则返回 null 还可以指示映射先前将 null 与键关联。)
computeIfAbsent
public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
从接口复制的描述:map
如果指定的键尚未与值关联(或映射为 null),则尝试使用给定的映射函数计算其值并将其输入到此映射中,除非为 null。
如果函数返回 null,则不记录映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并且不记录任何映射。 最常见的用法是构造一个新对象作为初始映射值或记忆结果,如下所示:
map.computeIfAbsent(key, k -> new Value(f(k)));
或者实现一个多值映射,Map<K,Collection<V>>,每个键支持多个值:
map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
指定者:
接口 MapK,V 中的 computeIfAbsent
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
mappingFunction | 计算值的函数 |
返回:
与指定键关联的当前(现有或计算的)值,如果计算的值为 null,则为 null
computeIfPresent
public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
从接口复制的描述:地图
如果指定键的值存在且非空,则尝试在给定键及其当前映射值的情况下计算新映射。
如果函数返回 null,则删除映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并且当前映射保持不变。
指定者:
接口 MapK,V 中的 computeIfPresent
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
remappingFunction | 计算值的函数 |
返回:
与指定键关联的新值,如果没有,则为 null
compute
public V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
从接口复制的描述:Map
尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为 null)。 例如,要创建或附加 String msg 到值映射:
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
(方法 merge() 通常更容易用于此类目的。)
如果函数返回 null,则删除映射(如果最初不存在,则保持不存在)。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并且当前映射保持不变。
指定者:
在接口 MapK,V 中计算
参数:
参数名称 | 参数描述 |
---|---|
key | 与指定值关联的键 |
remappingFunction | 计算值的函数 |
返回:
与指定键关联的新值,如果没有,则为 null
merge
public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
从接口复制的描述:Map
如果指定的键尚未与值关联或与 null 关联,则将其与给定的非 null 值关联。 否则,将关联的值替换为给定重映射函数的结果,如果结果为 null,则将其删除。 当为一个键组合多个映射值时,此方法可能很有用。 例如,要创建或附加 String msg 到值映射:
map.merge(key, msg, String::concat)
如果函数返回 null,则删除映射。 如果函数本身抛出(未经检查的)异常,则重新抛出异常,并且当前映射保持不变。
指定者:
在接口 MapK,V 中合并
参数:
参数名称 | 参数描述 |
---|---|
key | 与结果值关联的键 |
value | 要与键关联的现有值合并的非空值,或者如果没有现有值或空值与键关联,则与键关联 |
remappingFunction | 重新计算值的函数(如果存在) |
返回:
与指定键关联的新值,如果没有值与该键关联,则为 null
forEach
public void forEach(BiConsumer<? super K,? super V> action)
从接口复制的描述:地图
对该映射中的每个条目执行给定的操作,直到处理完所有条目或该操作引发异常。 除非实现类另有规定,否则按照条目集迭代的顺序执行动作(如果指定了迭代顺序)。动作抛出的异常将转发给调用者。
指定者:
接口 MapK,V 中的 forEach
参数:
参数名称 | 参数描述 |
---|---|
action | 为每个条目执行的操作 |
replaceAll
public void replaceAll(BiFunction<? super K,? super V,? extends V> function)
从接口复制的描述:地图
将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都已处理或该函数引发异常。 函数抛出的异常被转发给调用者。
指定者:
接口 MapK,V 中的 replaceAll
参数:
参数名称 | 参数描述 |
---|---|
function | 应用于每个条目的函数 |
clone
public Object clone()
返回此 HashMap 实例的浅表副本:键和值本身没有被克隆。
覆盖:
在类 AbstractMapK,V 中克隆
返回:
这个 map 的浅拷贝