Java Map映射的用法(附带实例)
映射(Map)是一种存储键和值之间关联关系的数据结构。可以调用 put() 添加新的关联关系,或更改现有键的值:
下面是获取一对键和值的方式:
当需要更新映射中的计数器时,首先需要检查计数器是否存在,如果存在,则将现有值加 1。下面的 merge() 方法简化了这个常见操作。以下调用:
下表总结了映射操作:
通过调用以下方法,可以获得映射的键、值和条目的视图:
要遍历映射中的所有键和值,可以迭代 entrySet() 方法返回的集合:
如果想将条目传递给其他方法,应该通过调用 Map.Entry.copyOf(entry) 方法取消与映射的连接。也可以通过调用 Map.entry(key, value) 来创建一个未关联的 Map.Entry 实例。当需要一对值时,这是一个快捷的途径。
注意,某些映射实现(如 ConcurrentHashMap)不允许键或值为 null。而对于那些允许使用 null 值的映射实现(如HashMap),如果使用 null 值,那么需要非常小心。许多映射方法将 null 解释为条目不存在或应该被删除的指示。
此外,有时需要以不同于排序顺序的顺序显示映射中的键。例如,在 JavaServer Faces 框架中,使用映射指定选择框的标签和值。如果选项按字母顺序(其英文字母顺序为:星期五、星期一、星期六、星期日、星期四、星期二、星期三)或按哈希码顺序排序,用户会感到很困惑。在这种情况下,可以使用一个 LinkedHashMap,它会记住条目添加的顺序,并按照该顺序迭代它们。
var counts = new HashMap<String, Integer>(); counts.put("Alice", 1); // Adds the key/value pair to the map counts.put("Alice", 2); // Updates the value for the key这个例子使用了一个哈希映射。和集合类似,当不需要按排序顺序访问键时,哈希映射通常是一个更好的选择。如果需要按排序顺序访问键,可以改用 TreeMap 映射。
下面是获取一对键和值的方式:
int count = counts.get("Alice");如果键不存在,则 get() 方法将返回 null。在本例中,当值进行拆箱操作时将导致 NullPointerException 异常。因此,更好的选择是使用以下代码:
int count = counts.getOrDefault("Alice", 0);如果键不存在,则返回值为 0。
当需要更新映射中的计数器时,首先需要检查计数器是否存在,如果存在,则将现有值加 1。下面的 merge() 方法简化了这个常见操作。以下调用:
counts.merge(word, 1, Integer::sum);如果该键原先不存在,则将 word 与 1 关联,否则使用 Integer::sum() 函数将原值与 1 进行组合。
下表总结了映射操作:
方法 | 功能描述 |
---|---|
V get(Object key) | 如果 key 与非 null 值 v 相关联,则返回 v,否则返回 null。 |
V getOrDefault(Object key, V defaultValue) | 如果 key 与非 null 值 v 相关联,则返回 v,否则返回 defaultValue |
V put(K key, V value) | 如果 key 与非 null 值 v 相关联,则将 key 与 value 关联并返回 v。否则,添加条目并返回 null |
V putIfAbsent(K key, V value) | 如果 key 和非 null 值 v 相关联,则忽略 value 并返回 v。否则,添加条目并返回 null |
V merge(K key, V value, BiFunctionremappingFunction) | 如果 key 与非 null 值 v 相关联,则将函数应用于 v 和 value,并将 key 与结果关联,或者如果结果为 null,则删除key。否则,将 key 与 value 关联。返回 get(key) |
V compute(K key, BiFunctionremappingFunction) | 将函数应用于 key 和 get(key)。将 key 与结果关联,或者如果结果为 null,则删除 key。返回 get(key) |
V computeIfPresent(K key, BiFunctionremappingFunction) | 如果 key 与非 null 值 v 相关联,则将函数应用于 key 和 v,并将 key 与结果关联,或者如果结果为 null,则删除 key。返回 get(key) |
V computeIfAbsent(K key, FunctionmappingFunction) | 将函数应用于 key,除非 key 与非 null 值相关联。将 key 与结果关联,或者如果结果为 null,则删除 key。返回 get(key) |
void putAll(Mapm) | 添加 m 中的所有条目 |
V remove(Object key) | 删除 key 及其关联值,返回旧值,如果不存在则返回 null |
V replace(K key, V newValue) | 替换旧值,返回旧值,如果不存在则返回 null |
boolean remove(Object key, Object value) | 如果 key 与 value 相关联,则删除条目并返回 true。否则,不执行任何操作并返回 false |
boolean replace(K key, V value, V newValue) | 如果 key 与 value 相关联,则替换旧值并返回 true。否则,不执行任何操作并返回 false |
int size() | 返回条目数量 |
boolean isEmpty() | 检查此映射是否为空 |
void clear() | 删除所有条目 |
void forEach(BiConsumeraction) | 将操作应用于所有条目 |
void replaceAll(BiFunctionfunction) | 对所有条目调用函数。将键与非 null 结果关联,并删除结果为 null 的键 |
boolean containsKey(Object key) | 检查映射是否包含给定的键 |
boolean containsValue(Object value) | 检查映射是否包含给定的值 |
Set |
返回键的视图 |
Collection |
返回值的视图 |
Set |
返回条目的视图 |
static Map |
生成一个不可修改的映射 |
static Map |
生成一个不可修改的映射,包含 1 个键和值 |
static Map |
生成一个不可修改的映射,包含 2 个键和值 |
... | 最多可包含 10 个键和值 |
通过调用以下方法,可以获得映射的键、值和条目的视图:
Set<K> keySet() Set<Map.Entry<K, V>> entrySet() Collection<V> values()返回的容器不是映射数据的副本,而是与映射相连的。如果从视图中删除键或条目,则该条目也将从基础映射中删除。
要遍历映射中的所有键和值,可以迭代 entrySet() 方法返回的集合:
for (Map.Entry<String, Integer> entry : counts.entrySet()) { String k = entry.getKey(); Integer oldValue = entry.getValue(); int newValue = ...; entry.setValue(newValue); }Map.Entry 实例也与映射相连。从前面的代码片段中可以看到,可以使用条目对象更新基础映射中的值。相反,如果通过其他方式(例如,通过调用映射的 put() 方法)更新值,则条目也会更新。
如果想将条目传递给其他方法,应该通过调用 Map.Entry.copyOf(entry) 方法取消与映射的连接。也可以通过调用 Map.entry(key, value) 来创建一个未关联的 Map.Entry 实例。当需要一对值时,这是一个快捷的途径。
注意,某些映射实现(如 ConcurrentHashMap)不允许键或值为 null。而对于那些允许使用 null 值的映射实现(如HashMap),如果使用 null 值,那么需要非常小心。许多映射方法将 null 解释为条目不存在或应该被删除的指示。
此外,有时需要以不同于排序顺序的顺序显示映射中的键。例如,在 JavaServer Faces 框架中,使用映射指定选择框的标签和值。如果选项按字母顺序(其英文字母顺序为:星期五、星期一、星期六、星期日、星期四、星期二、星期三)或按哈希码顺序排序,用户会感到很困惑。在这种情况下,可以使用一个 LinkedHashMap,它会记住条目添加的顺序,并按照该顺序迭代它们。