首页 > 编程笔记 > Java笔记 阅读:6

Java Map映射的用法(附带实例)

映射(Map)是一种存储键和值之间关联关系的数据结构。可以调用 put() 添加新的关联关系,或更改现有键的值:
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 进行组合。

下表总结了映射操作:

表:Map<K, V>方法
方法 功能描述
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 keySet() 返回键的视图
Collection values() 返回值的视图
Set> entrySet() 返回条目的视图
static Map of() 生成一个不可修改的映射
static Map of(K k1, V v1) 生成一个不可修改的映射,包含 1 个键和值
static Map of(K k1, V v1, K k2, V v2) 生成一个不可修改的映射,包含 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,它会记住条目添加的顺序,并按照该顺序迭代它们。

相关文章