接口 Map<K,V>
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射一个值。
此接口代替 Dictionary 类,后者完全是一个抽象类,而不是一个接口。
Map 接口提供三种collection 视图,允许以键集、值集合或键-值映射关系集的形式查看某个映射的内容。映射的顺序 定义为迭代器在映射的 collection 视图中返回其元素的顺序。某些映射实现可明确保证其顺序,如 TreeMap 类;某些映射实现则不保证顺序,如 HashMap 类。
注:将可变对象用作映射键时必须格外小心。当对象是映射中某个键时,如果以影响 equals 比较的方式更改了对象的值,则映射的行为就不是特定的。此项禁止的一个特殊情况是不允许某个映射包含其自身作为键。虽然允许某个映射包含其自身作为值,但建议要格外小心:在这样的映射上将无法再定义 equals 和 hashCode 方法。
所有通用的映射实现类应该提供两个“标准的”构造方法:一个 void(无参数)构造方法,用于创建空映射,另一个是带有 Map 类型单参数的构造方法,用于创建一个与其参数具有相同键-值映射关系的新映射。实际上,后一个构造方法允许用户复制任意映射,生成所需类的一个等价映射。尽管无法强制执行该建议(因为接口不能包含构造方法),但是 JDK 中所有通用的映射实现都遵从它。
该接口中包含的“破坏性”方法可修改其所操作的映射,如果此映射不支持该操作,则指定这些方法抛出 UnsupportedOperationException。如果是这样,那么在调用对该映射无效时,这些方法可能,但并不一定抛出 UnsupportedOperationException。例如,如果某个不可修改的映射(其映射关系是“重叠”的)为空,则对该映射调用 putAll(Map)
方法时,可能但并不一定抛出异常。
某些映射实现对可能包含的键和值有所限制。例如,某些实现禁止空键和空值,而某些实现则对其键的类型有限制。尝试插入不合格的键或值会抛出一个未经检查的异常,通常是 NullPointerException 或 ClassCastException。试图查询是否存在不合格的键或值可能抛出异常,或者只是简单地返回 false;某些实现将表现出前一种行为,而某些实现则表现后一种。较为常见的是,试图对不合格的键或值执行操作且该操作的完成不会导致不合格的元素被插入映射中时,将可能抛出一个异常,也可能操作成功,这取决于实现本身。这样的异常在此接口的规范中标记为“可选”。
此接口是 Java Collections Framework 的成员。
Collections Framework 接口中的很多方法是根据 equals
方法定义的。例如,contains(Object key)
方法的规范声明:“当且仅当此映射对于键 k 包含以下映射关系时才返回 true:(key==null ? k==null : key.equals(k))”。不 应将此规范解释为它暗指调用具有非空参数 key 的 Map.containsKey 会导致对任意的键 k 调用 key.equals(k)。可随意对各种实现执行优化,只要避免调用 equals 即可,例如,通过首先比较两个键的哈希码(Object.hashCode()
规范保证哈希码不相等的两个对象不会相等)。较为常见的是,各种 Collections Framework 接口的实现可随意利用基础 Object
方法的指定行为,而不管实现程序认为它是否合适。
//方法
void clear()
从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射为指定值映射一个或多个键,则返回 true。
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 set 视图。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
V get(Object key)
返回此映射中映射到指定键的值。
int hashCode()
返回此映射的哈希码值。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
Set<K> keySet()
返回此映射中包含的键的 set 视图。
V put(K key, V value)
将指定的值与此映射中的指定键相关联(可选操作)。
void putAll(Map<? extends K,? extends V> t)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
V remove(Object key)
如果存在此键的映射关系,则将其从映射中移除(可选操作)。
int size()
返回此映射中的键-值映射关系数。
Collection<V> values()
返回此映射中包含的值的 collection 视图。
//嵌套类
static interface Map.Entry<K,V> 映射项(键-值对)。
Map提供接口分别用于返回 键集、值集或键-值映射关系集。
- entrySet()用于返回键-值集的Set集合
- keySet()用于返回键集的Set集合
- values()用户返回值集的Collection集合
因为Map中不能包含重复的键;每个键最多只能映射到一个值。所以,键-值集、键集都是Set,值集时Collection。
Map提供了“键-值对”、“根据键获取值”、“删除键”、“获取容量大小”等方法。
类 AbstractMap<K,V>
此类提供了 Map 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。
要实现不可修改的映射,程序员只需扩展此类并提供 entrySet 方法的实现即可,该方法将返回映射的映射关系 Set 视图。通常,返回的 Set 将依次在 AbstractSet 上实现。此 Set 不支持 add 或 remove 方法,其迭代器也不支持 remove 方法。
要实现可修改的映射,程序员还必须另外重写此类的 put 方法(否则将抛出 UnsupportedOperationException),并且由 entrySet().iterator() 所返回的迭代器必须另外实现其 remove 方法。
void clear()
从此映射中移除所有映射关系(可选操作)。
protected Object clone()
返回此 AbstractMap 实例的浅表复制:不克隆键和值本身。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射将一个或多个键映射到该值,则返回 true。
abstract Set<Map.Entry<K,V>> entrySet()
返回包含在此映射中的映射关系的 Set 视图。
boolean equals(Object o)
比较指定对象与此映射的相等性。
V get(Object key)
返回此映射将指定键映射到的值。
int hashCode()
返回此映射的哈希码值。
boolean isEmpty()
如果此映射不包含任何键-值映射关系,则返回 true。
Set<K> keySet()
返回包含在此映射中的键的 Set 视图。
V put(K key, V value)
将指定的值与此映射中的指定键关联起来(可选操作)。
void putAll(Map<? extends K,? extends V> t)
将指定映射的所有映射关系复制到此映射中(可选操作)。
V remove(Object key)
如果此映射中存在此键的映射关系,则移除该映射关系(可选操作)。
int size()
返回此映射中键-值映射关系的数量。
String toString()
返回此映射的字符串表示形式。
Collection<V> values()
返回包含在此映射中的值的 collection 视图。
有两个成员变量:
- keySet, 保存 map 中所有键的 Set
- values, 保存 map 中所有值的集合
他们都是 transient, volatile, 分别表示不可序列化、并发环境下变量的修改能够保证线程可见性。需要注意的是 volatile 只能保证可见性,不能保证原子性,需要保证操作是原子性操作,才能保证使用 volatile 关键字的程序在并发时能够正确执行。
AbstractMap 也有两个内部类:
- SimpleImmutableEntry, 表示一个不可变的键值对
- SimpleEntry, 表示可变的键值对
它们唯一的区别在于SimpleImmutableEntry的setValue会抛出UnsupportedOperationException。