Map接口源码理解

35 篇文章 0 订阅
本文详细介绍了Java中的Map接口,包括其概述、源码解析,特别是Entry接口的方法,如getKey、getValue、setValue等。同时,文章讨论了Map接口的各种方法,如size、isEmpty、equals、containsKey、containsValue、get、put、putAll、remove等,并提到了不可修改映射的创建方法of、ofEntries、copyOf。文章还详细解释了各种方法的行为和可能的异常情况。
摘要由CSDN通过智能技术生成


前言

本文章帮助大家对Map接口的理解。


一、概述

Map意为映射。顾名思义,此类可以将键和值映射起来,是同一类“键值对”(元素)的“集合”(非Collection,参考Collection接口),类似Dictionary抽象类,但后者比较局限,不推荐使用,参考Dictionary抽象类。其不能包含相同的键,一个键最多只能映射一个值。要使用键值对功能的话,推荐使用此接口。

其虽非Collection,但对键、值、键值对的集合提供集合视图。元素顺序由其对应集合视图的迭代器定义。

ofofEntriescopyOf静态方法可以创建不可修改的映射容器(下简称“映射”),即不能增加、删除、修改其元素。但若元素本身是可修改的,其修改会导致不一致的行为。其键、值均不能为空。其迭代顺序是不确定的。

二、源码理解

package java.util;
import java.util.Map;

使用Map接口时,需引入此包。

Map接口

public interface Map<K, V> { /*...*/ }

使用接口时传入泛型KV,为键、值的类型。

注意:若元素的键是可修改对象,其修改会导致不确定的行为,其中一种情况就是将其实现类对象作为其元素的键。其实现类对象不能作为其元素的值,否则导致其equalshashCode等方法不能很好地定义。很多方法需要用到equalshashCode方法。

注意:要求其实现类遵守如此规定:需实现两个构造函数:一个无参数构造函数,以创建一个空映射;一个参数为Map类型的构造函数,以创建一个具有和参数相同元素的映射。但由于接口不能包含构造函数,所以无法强制执行此规定。

但Java平台库中的所有通用映射实现都符合此约定。

Entry

Entry意为。顾名思义,它提供映射的项的结构(这里称该映射为其“支持映射”)。

interface Entry<K, V> { /*...*/ }

使用接口时传入泛型KV,为键、值的类型。

重点:若想要实现类是不可修改的,那么应该不实现其setValue方法。

Entry方法
getKey
K getKey();

返回键。若此项已从其支持映射删除,可抛出IllegalStateException异常。

getValue
V getValue();

返回值。若此项已从其支持映射删除,可抛出IllegalStateException异常。

setValue
V setValue(V value);

设置值,返回原值(可选)。

若其支持映射不支持put方法,则抛出UnsupportedOperationException异常;若因value的类而不能加入其支持映射中,则抛出ClassCastException异常;若value为空而其支持映射不允许有空值,则抛出NullPointerException异常;若因value的一些属性而不能加入其支持映射中,则抛出IllegalArgumentException异常;若此项已从其支持映射删除,可抛出IllegalStateException异常。

equals
boolean equals(Object o);

重写Object类的boolean equals(Object obj)方法,参考Object.equals方法。

判断此项与o的键值对是否相等。相等的条件为:o也实现了项接口且它们键、值均相等(equals)。

hashCode
int hashCode();

重写Object类的int hashCode()方法,参考Object.hashCode方法。

返回此项键、值的哈希码的异或。

comparingByKey
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> c1.getKey().compareTo(c2.getKey());
}

静态方法,传入泛型KV,为比较项的键、值类型,K继承Comparable<? super K>接口,需要是可比较的(即自身带有Comparable.compareTo方法)。返回比较项的比较器(实现Serializable接口)的比较结果同键的自然序比较结果。参考Comparator接口、Serializable接口、Comparable接口。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
    Objects.requireNonNull(cmp);
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}

静态方法,传入泛型KV,为比较项的键、值类型。返回比较项的比较器(实现Serializable接口)的比较结果同键的cmp比较器的比较结果。参考Comparator接口、Serializable接口。

cmp为空,则抛出NullPointerException异常。参考Objects.requireNonNull方法。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

comparingByValue
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}

静态方法,传入泛型KV,为比较项的键、值类型,V继承Comparable<? super V>接口,需要是可比较的(即自身带有Comparable.compareTo方法)。返回比较项的比较器(实现Serializable接口)的比较结果同值的自然序比较结果。参考Comparator接口、Serializable接口、Comparable接口。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
    Objects.requireNonNull(cmp);
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}

静态方法,传入泛型KV,为比较项的键、值类型。返回比较项的比较器(实现Serializable接口)的比较结果同值的cmp比较器的比较结果。参考Comparator接口、Serializable接口。

cmp为空,则抛出NullPointerException异常。参考Objects.requireNonNull方法。

若返回比较器中出现异常,那么这些异常会交给返回比较器的调用方处理。

copyOf
public static <K, V> Map.Entry<K, V> copyOf(Map.Entry<? extends K, ? extends V> e) {
    Objects.requireNonNull(e);
    if (e instanceof KeyValueHolder) {
        return (Map.Entry<K, V>) e;
    } else {
        return Map.entry(e.getKey(), e.getValue());
    }
}

静态方法,传入泛型KV,为返回项的键、值类型。返回键值同e的不可修改项。若e中存在为空的键或值,或e为空,则抛出NullPointerException异常。

注意:返回项通常是项参数的复制。

Map方法

size

int size();

返回元素个数。若映射包含元素个数大于Integer.MAX_VALUE,则返回Integer.MAX_VALUE

isEmpty

boolean isEmpty();

判断映射是否为空。

equals

boolean equals(Object o);

重写Object类的boolean equals(Object obj)方法,参考Object.equals方法。

判断此映射和对象o是否相同/相等。通常要返回true需要它们的项集相等。

hashCode

int hashCode();

重写Object类的int hashCode()方法,参考Object.hashCode方法。

返回此映射的哈希码。它定义为项集视图里所有项的哈希码的和(不同实现不一定是返回其和)。

containsKey

boolean containsKey(Object key);

判断映射是否包含键为对象key的项。通常认为找到一个键k,存在Objects.equals(key, k)则返回true

若对象key的类型和键类型不能比较,则抛出ClassCastException异常(可选);若对象key为空而映射不允许有空键,则抛出NullPointerException异常(可选)。

containsValue

boolean containsValue(Object value);

判断映射是否包含值为对象value的项。通常认为找到一个值v,存在Objects.equals(value, v)则返回true

若对象value的类型和键类型不能比较,则抛出ClassCastException异常(可选);若对象value为空而映射不允许有空值,则抛出NullPointerException异常(可选)。

大多实现要求此查询时间对于元素数量是线性的。

get

V get(Object key);

返回键为key的值。若查无键key,则返回空。通常认为找到一个键k,存在Objects.equals(key, k)则返回其值。

若对象key的类型和键类型不能比较,则抛出ClassCastException异常(可选);若对象key为空而映射不允许有空键,则抛出NullPointerException异常(可选)。

注意:返回空值不一定因为查无键key,有可能此映射允许值为空且查询到的值为空。可通过containsKey方法来区分这两种情况。

getOrDefault

default V getOrDefault(Object key, V defaultValue) { /*...*/ }

返回键为key的值。若查无键key,则返回defaultValuedefault关键字给出默认实现。

若对象key的类型和键类型不能比较,则抛出ClassCastException异常(可选);若对象key为空而映射不允许有空键,则抛出NullPointerException异常(可选)。

注意:查到值为空,也应返回空。

put

V put(K key, V value);

将键为key的值替换为value,并返回原来的值(可选)。若查无键key,则新增此键值对,返回空。

若实现类不支持put方法,则抛出UnsupportedOperationException异常;若因keyvalue的类而不能加入映射中,则抛出ClassCastException异常;若keyvalue为空而映射不允许有空键或值,则抛出NullPointerException异常;若因keyvalue的一些属性而不能加入映射中,则抛出IllegalArgumentException异常。

注意:返回空值不一定因为查无键key,有可能此映射允许值为空且查询到的值为空。可通过containsKey方法来区分这两种情况。

putIfAbsent

default V putIfAbsent(K key, V value) {
    V v = get(key);
    if (v == null) {
        v = put(key, value);
    }
    return v;
}

将键为key的不存在值的值替换为value。若查无键key,则新增此键值对,返回空;若查到值为空,则将其替换为value,返回空;否则不新增并返回原来的值。default关键字给出默认实现。

若实现类不支持put方法,则抛出UnsupportedOperationException异常(可选);若keyvalue的类型和此映射键或值的类型不能比较,则抛出ClassCastException异常(可选);若keyvalue为空而映射不允许有空键或值,则抛出NullPointerException异常(可选);若因keyvalue的一些属性而不能加入映射中,则抛出IllegalArgumentException异常(可选)。

注意:返回空值不一定因为查无键key,有可能此映射允许值为空且查询到的值为空,但结果都是新键值对存入映射中。可通过containsKey方法来区分这两种情况。

putAll

void putAll(Map<? extends K, ? extends V> m);

添加映射m的所有元素到此映射中(可选)。相当于对m中所有键值对进行一遍put操作。在此操作过程中,若修改此映射,那么此操作将出现为定义行为。

若实现类不支持putAll操作,则抛出UnsupportedOperationException异常;若因m中某键或值的类而不能加入此映射中,则抛出ClassCastException异常;若m中某键或值为空而此映射不允许有空键或值,或m为空,则抛出NullPointerException异常;若因m中某键或值的一些属性而不能加入此映射中,则抛出IllegalArgumentException异常。

remove

V remove(Object key);

从映射中移除键为key的元素,并返回原来的值(若有的话),若查无键key,则返回空(可选)。通常认为找到一个键k,存在Objects.equals(key, k)则移除。若成功移除,返回true

若实现类不支持remove操作,则抛出UnsupportedOperationException异常;若对象key的类型和键类型不能比较,则抛出ClassCastException异常(可选);若对象key为空而映射不允许有空键,则抛出NullPointerException异常(可选)。

注意:返回空值不一定因为查无键key,有可能此映射允许值为空且查询到的值为空。可通过containsKey方法来区分这两种情况。

default boolean remove(Object key, Object value) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, value) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    remove(key);
    return true;
}

从映射中移除键为key、值为value的元素,若成功移除,返回truedefault关键字给出默认实现。

若实现类不支持remove操作,则抛出UnsupportedOperationException异常(可选);若对象keyvalue的类型和键、值类型不能比较,则抛出ClassCastException异常(可选);若对象keyvalue为空而映射不允许有空键或值,则抛出NullPointerException异常(可选)。

注意:即使查到值为空,也要移除并返回true

replace

default boolean replace(K key, V oldValue, V newValue) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, oldValue) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    put(key, newValue);
    return true;
}

将映射中键为key、值为oldValue的项的值替换为newValue,若成功替换,返回truedefault关键字给出默认实现。

若实现类不支持put操作,则抛出UnsupportedOperationException异常(可选);若因替换键或值的类而不能加入此映射中,则抛出ClassCastException异常;若对象keynewValue为空而映射不允许有空键或值,或oldValue为空而映射不允许有空值(可选),则抛出NullPointerException异常;若因替换键或值的一些属性而不能加入此映射中,则抛出IllegalArgumentException异常。

注意:即使查到值为空,也要替换并返回true

default V replace(K key, V value) {
    V curValue;
    if (((curValue = get(key)) != null) || containsKey(key)) {
        curValue = put(key, value);
    }
    return curValue;
}

将映射中键为key的项的值替换为value,若成功替换,返回原值,否则返回空。default关键字给出默认实现。

若实现类不支持put操作,则抛出UnsupportedOperationException异常(可选);若因替换键或值的类而不能加入此映射中,则抛出ClassCastException异常(可选);若对象keyvalue为空而映射不允许有空键或值,则抛出NullPointerException异常;若因替换键或值的一些属性而不能加入此映射中,则抛出IllegalArgumentException异常。

注意:只要查到键,就要替换。

replaceAll

default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { /*...*/ }

替换此映射中的各个值,替换规则由二元函数式function给定,参考BiFunction接口。default关键字给出默认实现,实现中用项集的迭代器遍历每个键和值,用functionapply方法转化设置元素。

function函数式返回空而此映射不允许有空值(可选),或function为空,则抛出NullPointerException异常;若此映射不可修改,或项集的迭代器不支持set方法,则抛出UnsupportedOperationException异常;若替换值的类型和此映射值类型不能比较(可选),或因替换值的类而不能加入此映射中,则抛出ClassCastException异常;若因替换值的一些属性而不能加入此映射中,则抛出IllegalArgumentException异常(可选);若遍历过程中有项被移除,则抛出ConcurrentModificationException异常。

computeIfAbsent

default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { /*...*/ }

将键为key的不存在值的值替换为mappingFunction的计算结果。若查无键key或查到值为空,若keymappingFunction函数式计算结果为空,不处理并返回空,否则设键key值为计算结果并返回新值;若查键key值非空,不处理并返回原值。default关键字给出默认实现。

若实现类不支持put方法,则抛出UnsupportedOperationException异常(可选);若keyvalue的类型和此映射键或值的类型不能比较,则抛出ClassCastException异常(可选);若keyvalue为空而映射不允许有空键或值,则抛出NullPointerException异常(可选);若因keyvalue的一些属性而不能加入映射中,则抛出IllegalArgumentException异常(可选)。

注意:默认实现没有检测mappingFunction计算过程有没修改此映射,非并发实现 应在检测到其修改映射时抛出ConcurrentModificationException异常,并发实现应在检测到其修改映射时抛出IllegalStateException异常。

computeIfPresent

default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { /*...*/ }

将键为key的存在值的值替换为remappingFunction的计算结果。若查键key值非空,若key、原值经remappingFunction二元函数式计算结果为空,移除此键并返回空,否则设键key值为计算结果并返回新值;若查无键key或查到值为空,不处理并返回空。default关键字给出默认实现。

若实现类不支持put方法,则抛出UnsupportedOperationException异常(可选);若因key或计算结果的类而不能加入映射中,则抛出ClassCastException异常(可选);若key为空而映射不允许有空键,或remappingFunction为空,则抛出NullPointerException异常;若因key或计算结果的一些属性而不能加入映射中,则抛出IllegalArgumentException异常(可选)。

注意:默认实现没有检测remappingFunction计算过程有没修改此映射,非并发实现 应在检测到其修改映射时抛出ConcurrentModificationException异常,并发实现应在检测到其修改映射时抛出IllegalStateException异常。

compute

default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { /*...*/ }

将键为key的值替换为remappingFunction的计算结果。若key、原值(或空)经remappingFunction二元函数式计算结果为空,若查有此键,移除此键并返回空,否则返回空;若计算结果非空,设键key值为计算结果并返回新值。default关键字给出默认实现。

若实现类不支持put方法,则抛出UnsupportedOperationException异常(可选);若因key或计算结果的类而不能加入映射中,则抛出ClassCastException异常(可选);若key为空而映射不允许有空键,或remappingFunction为空,则抛出NullPointerException异常;若因key或计算结果的一些属性而不能加入映射中,则抛出IllegalArgumentException异常(可选)。

注意:默认实现没有检测remappingFunction计算过程有没修改此映射,非并发实现 应在检测到其修改映射时抛出ConcurrentModificationException异常,并发实现应在检测到其修改映射时抛出IllegalStateException异常。

merge

default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { /*...*/ }

将键为key的值与value合并。若查无键key或查到值为空,则新值为value,否则新值为原值、valueremappingFunction二元函数式计算结果。若新值为空,移除此键并返回空;否则设键key值为计算结果并返回新值。default关键字给出默认实现。

若实现类不支持put方法,则抛出UnsupportedOperationException异常(可选);若因key或计算结果的类而不能加入映射中,则抛出ClassCastException异常(可选);若key为空而映射不允许有空键,或valueremappingFunction为空,则抛出NullPointerException异常;若因key或计算结果的一些属性而不能加入映射中,则抛出IllegalArgumentException异常(可选)。

注意:默认实现没有检测remappingFunction计算过程有没修改此映射,非并发实现 应在检测到其修改映射时抛出ConcurrentModificationException异常,并发实现应在检测到其修改映射时抛出IllegalStateException异常。

clear

void clear();

清空此映射(可选)。若实现类不支持clear操作,则抛出UnsupportedOperationException异常。

keySet

Set<K> keySet();

返回此映射的所有键的Set集合视图。参考Set接口。

重点:返回集合受此映射支撑,对返回集合的非结构修改也会反映到此映射上,反之亦然。

注意:返回视图及其迭代器的删除操作可删除映射中对应键的项,但不支持添加操作。若在迭代遍历时映射进行修改操作,将导致不确定的行为。

values

Collection<V> values();

返回此映射的所有值的Collection集合视图。参考Collection接口。

重点:返回集合受此映射支撑,对返回集合的非结构修改也会反映到此映射上,反之亦然。

注意:返回视图及其迭代器的删除操作可删除映射中对应值的项,但不支持添加操作。若在迭代遍历时映射进行修改操作,将导致不确定的行为。

entrySet

Set<Map.Entry<K, V>> entrySet();

返回此映射的所有项的Set集合视图。

重点:返回集合受此映射支撑,对返回集合的非结构修改也会反映到此映射上,反之亦然。

注意:返回视图及其迭代器的删除操作可删除映射中对应项,但不支持添加操作。若在迭代遍历时映射进行修改操作,将导致不确定的行为。

forEach

default void forEach(BiConsumer<? super K, ? super V> action) { /*...*/ }

遍历所有元素的键和值(遍历顺序为项集的迭代顺序),对其调用action。参考BiConsumer接口。default关键字给出默认实现。

若参数为空,则抛出NullPointerException异常;若遍历过程中有项被移除,则抛出ConcurrentModificationException异常。

of

static <K, V> Map<K, V> of() {
    return (Map<K,V>) ImmutableCollections.EMPTY_MAP;
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回不包含元素的不可修改映射。参考ImmutableCollections类。

static <K, V> Map<K, V> of(K k1, V v1) {
    return new ImmutableCollections.Map1<>(k1, v1);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。若存在为空的参数,则抛出NullPointerException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                           K k6, V v6) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                           k6, v6);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                           K k6, V v6, K k7, V v7) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                           k6, v6, k7, v7);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                           K k6, V v6, K k7, V v7, K k8, V v8) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                           k6, v6, k7, v7, k8, v8);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                           K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                           k6, v6, k7, v7, k8, v8, k9, v9);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                           K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
    return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                           k6, v6, k7, v7, k8, v8, k9, v9, k10, v10);
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。类似of(K k1, V v1)方法,若键有重复值,则抛出IllegalArgumentException异常。

ofEntries

static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) { /*...*/ }

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含参数元素的不可修改映射。若存在为空的参数(包括其键、值),或数组参数为空,则抛出NullPointerException异常,若参数有重复键,则抛出IllegalArgumentException异常。

注意:此方法与of方法参数不同,此方法参数为项数组,非数个键和值。

entry

static <K, V> Entry<K, V> entry(K k, V v) {
    return new KeyValueHolder<>(k, v);
}

静态方法,传入泛型KV,为返回项的键、值类型。返回键、值为参数的不可修改项。若存在为空的参数,则抛出NullPointerException异常。参考KeyValueHolder类。

copyOf

static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) {
    if (map instanceof ImmutableCollections.AbstractImmutableMap) {
        return (Map<K,V>)map;
    } else {
        return (Map<K,V>)Map.ofEntries(map.entrySet().toArray(new Entry[0]));
    }
}

静态方法,传入泛型KV,为返回映射的键、值类型。返回包含映射map的所有元素的不可修改映射。若映射map中存在为空的键或值,或映射map为空,则抛出NullPointerException异常。

注意:返回映射通常是映射参数的复制(使用了Set.toArray进行复制,使用了ofEntries方法包含非空检验。参考Set.toArray方法),原映射修改不会影响到返回映射,但如果参数映射是不可修改映射,那么返回映射通常不是它的复制(即返回参数本身(本就有非空检验))。


总结

新人源码理解,望大家多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值