【Java集合框架】3 - 9 Map 双列集合顶级接口

§3-9 Map 双列集合顶级接口

3-9.1 双列集合类体系结构

在正式开始学习 Map 双列集合前,先来看看双列集合的类结构:

image

同样地,这里双列集合也包含了用于并发编程的并发集合,这些集合在并发环境下是线程安全的,这些集合会在多线程与 JUC 并发编程中介绍。

3-9.2 双列集合常用的数据结构

Map 双列集合常用的数据结构如下图所示:

image

Map 体系的集合是双列集合,一次存储一对数据 <K,V>,称为一个键值对(或键值对对象、Entry 对象)。

其中,K 为键(key),V 为值。键唯一,而值可能不唯一,且键与值一一对应。

Hashtable 及其子类 Properties 涉及与 IO 有关的方法,此处暂不考虑。

3-9.3 Map 接口

Map 是双列集合的父类接口,其功能可以由所有双列集合使用。

方法

方法 描述
V put(K key, V value) 添加键值对
V remove(Object key) 根据键删除指定键值对元素
void clear() 清空当前集合
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
Set<K> keySet() 返回该集合所有键构成的 Set 集合
Collection<V> values() 返回该集合所有值构成的 Collection 集合
V get(Object key) 返回指定键所映射的值
boolean isEmpty() 判断集合是否为空
int size() 返回集合的长度,即集合中键值对个数

注意

  • put 方法具有覆盖功能,该方法会将指定键所对应的值用新值覆盖,并返回旧值;
  • get 方法若找不到对应地的值,则返回 null
  • 创建 Map的实现类对象时,注意应当传入两个泛型参数;

3-9.4 遍历方式

Map 内元素有多种不同的遍历方式。

3-9.4.1 键找值

Map 中所有的键抽取出来,并存放到一个单列集合中。再遍历该单列集合,对每个元素使用 get 方法获取对应值。

在单列集合中,则可以使用 Collection 的三种遍历方式,示例

//遍历方式
//键找值:获取键的Set集合,用 get 获取值
Set<String> keys = map.keySet();

//迭代器
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
    String key = it.next();
    System.out.println(key + "=" + map.get(key));
}
System.out.println("==============");

//增强 for
for (String key : keys) {
    System.out.println(key + "=" + map.get(key));
}
System.out.println("==============");

//forEach
keys.forEach(key -> {
    System.out.println(key + "=" + map.get(key));
});
System.out.println("==============");

3-9.4.2 键值对

Map 中的键值对直接打包成一个 Set 集合返回。再遍历该单列集合,通过 getKeygetValue 方法获取键和值。

Entry<K,V>Map 中的一个内部接口,可直接通过 Map.Entry<K,V> 访问。

示例

//键值对
Set<Map.Entry<String, String>> entries = map.entrySet();

//迭代器
Iterator<Map.Entry<String, String>> it2 = entries.iterator();
while (it2.hasNext()) {
    Map.Entry<String, String> next = it2.next();
    System.out.println(next.getKey() + "=" + next.getValue());
}
System.out.println("==============");

//增强 for
for (Map.Entry<String, String> entry : entries) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}
System.out.println("==============");

//forEach
entries.forEach(entry -> {
    System.out.println(entry.getKey() + "=" + entry.getValue());
});
System.out.println("==============");

3-9.4.3 Lambda 表达式

JDK 8 引入了 Lambda 表达式,提供了一种更简单、更直接的遍历方式。

方法 描述
default void forEach(BiConsumer<? super K, ? super V> action) 结合 Lambda 表达式遍历集合

该方法位于 Map 接口中,其中,BiConsumer<T,U> 是一个位于 java.util.function 的函数式接口,其内部含有一个抽象方法 accepct,用于执行接收两个参数但无返回值的操作,类似于 Consumer 中的 accepct 方法,可用 Lambda 表达式简化。

forEach 默认方法体

default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch (IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        action.accept(k, v);
    }
}

示例

//forEach:匿名内部类
map.forEach(new BiConsumer<String, String>() {
    @Override
    public void accept(String key, String value) {
        System.out.println(key + "=" + value);
    }
});
System.out.println("==============");

//forEach:Lambda
map.forEach((key, value) -> System.out.println(key + "=" + value));
System.out.println("==============");
posted @ 2023-08-09 22:19  Zebt  阅读(38)  评论(0)    收藏  举报