在 Java 中,Map 是一种将键与值关联起来的数据结构,可以高效地存储、访问、更新和删除键值对。与只存储元素的集合不同,Map 维护的是一种映射关系,其中每个键都是唯一的,并且指向一个值,但多个键可以对应相同的值。

Map 接口提供了通过唯一(不重复)的键获取值的机制。它还提供了三种集合视图,使我们能够以不同方式操作 Map 的内容:键的集合、值的集合,或者键和值之间映射关系的集合。从 Map 派生的主要接口是表示有序 Map 的 SortedMap,以及它的子接口 NavigableMap。Map 被标准库中的许多类广泛使用。对于非并发 Map,实现 Map 接口的主要类是 HashMap、LinkedHashMap 和 TreeMap。对于并发 Map,主要的类是 ConcurrentHashMap 和 ConcurrentSkipListMap。

下面是 Map 接口定义的一部分,其中只包含主要的方法:

public interface Map<K,V>{
    // Query Operations
    int size();
    boolean isEmpty();
    boolean containsKey(Object key);
    boolean containsValue(Object value);
    V get(Object key);

    // Modification Operations
    V put(K key, V value);
    V remove(Object key);
    void putAll(Map<? extends K, ? extends V> m);
    void clear();

    // Views
    Set<K> keySet();
    Collection<V> values();
    Set<Map.Entry<K, V>> entrySet();

    // Definition of the Entry interface
    interface Entry<K, V> {
        // Body omitted
    }

    // (continues...)
}

下面的示例展示了一个汽车 Map,其中键是车牌号,值是相应汽车型号的名称。通过这个 Map,我们可以使用键作为 containsKey 方法的参数来检查某个元素是否存在。此外,get 方法可以获取与作为参数传入的键关联的值,而 remove 方法可以从 Map 中删除该条目:

void main() {
    Map<String, String> cars = new HashMap<>();
    cars.put("ABCD2935", "Tesla Model S");
    cars.put("YJKF9353", "Toyota Corolla");
    cars.put("WFLO1304", "Honda CRV");

    var key = "ABCD2935";

    if (cars.containsKey(key)){
        IO.println("Vehicle data:");
        IO.println(cars.get(key));
        IO.println("Removing the vehicle...");
        cars.remove(key);
    } else
        IO.println("Vehicle not found!");
}
Vehicle data:
Tesla Model S
Removing the vehicle...

除了上面介绍的方法之外,还有一些提供额外功能的 default 方法。

该接口还提供了用于根据给定值创建不可变 Map 的方法(of 和 ofEntries 方法,以及辅助方法 entry),以及根据已有 Map 创建不可变 Map 的方法(copyOf)。

图 1 展示了 Map 接口及其主要子接口。Map 的直接子接口包括 SequencedMap、Bindings 和 ConcurrentMap。间接而言,SortedMap、NavigableMap 和 ConcurrentNavigableMap 也是从 Map 派生的接口(后者同时还是 ConcurrentMap 的子接口)。

Map 接口及其子接口

Map 最重要的派生接口包括 SortedMap 和 NavigableMap。

SortedMap 接口扩展了 SequencedMap 接口,用于表示按照特定顺序维护键的 Map。该顺序可以按照键的自然顺序确定,也可以按照创建 Map 时提供的特定比较器确定。NavigableMap 是 Collections Framework 中 SortedMap 唯一的直接子接口,它增加了用于对 Map 的键执行更高级导航操作的方法,例如获取与某个特定值最接近的键,或者按照升序或降序遍历 Map。

在实践中,我们通常使用 NavigableMap 而不是 SortedMap,因为 Collections Framework 中实现 SortedMap 的两个类都是间接实现的(TreeMap 实现 NavigableMap,而 ConcurrentSkipListMap 实现 ConcurrentNavigableMap)。NavigableMap 在功能上更进一步,提供了用于在 Map 中进行导航的专用方法,其方式类似于 NavigableSet 为集合提供的功能。


本文内容改编自 Orientação a Objetos com Java 一书,作者为 Eduardo Kessler Piveta。