目录
一,Map
1.1 Map 接口分析
1.2 Map 查询业务接口
1.3 Map 修改(写)业务接口
1.4 Map 批量业务接口
1.5 Map 视图业务
1.6 Map 的映射业务Entry
1.7 Map 不可修改的业务
二,AbstractMap
2.1 AbstractMap 构造方法
2.2 AbstractMap 查询业务
2.2.1 size()
2.2.2 isEmpty()
2.2.3 containsValue(value)
2.2.4 containsKey(key)
2.2.5 get(key)
2.3 AbstractMap 修改(写)业务
2.3.1 put(key,value)
2.3.2 remove(key)
2.4 AbstractMap 批量业务
2.4.1 putAll(m)
2.4.2 clear()
2.5 AbstractMap 视图业务
2.5.1 keySet()
2.5.2 values()
2.5.3 entrySet()
2.6 Comparison & hashing
2.6.1 equals(o)
2.6.2 hashCode()
2.7 AbstractMap 其他业务
2.7.1 toString()
2.7.2 clone()
2.7.3 eq(o1, o2)
2.8 AbstractMap 映射实体Entry接口实现
2.8.1 简单映射实体
2.8.2 不可修改的映射实体
三,AbstractImmutableMap
3.1 Map1 & MapN
3.2 Map1 和 MapN 的区别
一,Map
Map 是一个键值对的集合,它取代了 java.util.Dictionary 字典类;这个字典类是在 JDK1.0 提供的,Map集合是在 JDK1.2 提供的。
1.1 Map 接口分析
package java.util;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {/*忽略代码*/}
1.2 Map 查询业务接口
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 查询业务 **************************/
/** map集合大小 */
int size();
/**
* map集合是否为空;
* @retrun true- 为空 | false - 不为空
*/
boolean isEmpty();
/**
* 是否包含指定的key
* @retrun true - 包含 | false - 不包含
*/
boolean containsKey(Object key);
/**
* 是否包含指定的value
* @retrun true - 包含 | false - 不包含
*/
boolean containsValue(Object value);
/** 根据key获取value; 如果没有返回为null */
V get(Object key);
/*忽略其他代码*/
}
1.3 Map 修改(写)业务接口
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 修改业务 **************************/
/**
* 新增键值对
*
* @param key 要新增的key
* @param value 要新增的value
* @return 返回key关联的前一个值,如果没有则返回null
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
* @throws IllegalArgumentException 非法参数异常
*/
V put(K key, V value);
/**
* 删除map集合中对应的key-value 键值对
*
* @param key
* @return 返回key前一个映射的值
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
*/
V remove(Object key);
//... ...
}
1.4 Map 批量业务接口
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 批量业务 **************************/
/**
* 新增指定的元素集
*
* @param m 要新增的map元素集合
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
* @throws IllegalArgumentException 非法参数异常
*/
void putAll(Map<? extends K, ? extends V> m);
/**
* 清空Map集合
* @throws UnsupportedOperationException 不支持操作异常
*/
void clear();
}
1.5 Map 视图业务
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map的试图业务 **************************/
/**
* 获取 key 的所有元素,并以Set形式进行返回;
*/
Set<K> keySet();
/**
* 获取 values 的所有元素,并以Collection形式进行返回
*/
Collection<V> values();
/**
* 获取 key-value 的所有元素,并以Set形式进行返回;类型是Map.Entry
*/
Set<Map.Entry<K, V>> entrySet();
/*忽略其他代码*/
}
1.6 Map 的映射业务Entry
map 是一个 key-value 的映射集合;映射业务标准定义由Entry实现;Entry 中文名称为“实体”的意思;也就是Map的元素表现就是以的形式 Entry 呈现; Entry 里面包含着 key与value ;
那为什么不直接定义为一个 实体类 calss Entry, 然后指定定义属性key,value,再定义getting与setting呢?
首先,接口的作用是什么?接口的作用是提供标准。没错 interface Entry 接口是为了提供映射业务实现的标准;从而不限制 Entry的具体实现方式;具体的子类可以根据自己具体的子类特性进行实现;(可参考 AbstractMap的Entry的实现)
如果在定义Map 接口的时候,就将Entry写成一个实体类,就意味着Map的Entry实现方式就只有一种固定的,可能无法满足不同子类的需求
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 的映射业务 Entry **************************/
/**
* map 是一个 key-value 的映射集合;映射业务标准定义由Entry实现;
* Entry 中文名称为“实体”的意思;也就是Map的元素表现就是 Entry ;
* Entry 里面包含着 key与value ;
* 那为什么不直接定义为一个 实体类 calss Entry, 然后指定定义属性key,value,再定义getting与setting呢?
* 首先,接口的作用是什么?接口的作用是提供标准。没错interface Entry 是为了提供映射业务实现的标准;从而不限制 Entry的具体实现方式;具体的子类可以根据自己的特性进行实现;
* 如果在定义Map 接口的时候,就将Entry写成一个实体类,就意味着Map的Entry实现方式就只有一种固定的,可能无法满足不同子类的需求
* @see Map#entrySet()
* @since 1.2
*/
interface Entry<K, V> {
/** 获取 key */
K getKey();
/** 获取 value */
V getValue();
/** 设置 value */
V setValue(V value);
/** 比较Entry是否相同 */
boolean equals(Object o);
/** 获取hashCode */
int hashCode();
/**
* @return 根据key进行自然比较
* @see Comparable
* @since 1.8
*/
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());
}
/**value
* @return 根据value进行自然比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* @return 根据key进行比较器进行比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* @return 根据value进行比较器进行比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* 复制一个Map.Entry 实体
* @since 17
*/
@SuppressWarnings("unchecked")
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());
}
}
}
/*忽略其他代码*/
}
1.7 Map 不可修改的业务
JDK9 提供一些列的不可修改操作
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 不可修改业务 **************************/
/**
* 返回包含0映射实体的不可修改映射Map
* @since 9
*/
@SuppressWarnings("unchecked")
static <K, V> Map<K, V> of() {
return (Map<K,V>) ImmutableCollections.EMPTY_MAP;
}
/**
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1) {
return new ImmutableCollections.Map1<>(k1, v1);
}
/**
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
return new ImmutableCollections.MapN<>(k1, v1, k2, v2);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
}
完整代码如下:
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable;
/**
* @param <K> 键的类型
* @param <V> 值的类型
*
* @author Josh Bloch
* @since 1.2
*/
public interface Map<K, V> {
/*********************** Map 查询业务 **************************/
/** map集合大小 */
int size();
/**
* map集合是否为空;
* @retrun true- 为空 | false - 不为空
*/
boolean isEmpty();
/**
* 是否包含指定的key
* @retrun true - 包含 | false - 不包含
*/
boolean containsKey(Object key);
/**
* 是否包含指定的value
* @retrun true - 包含 | false - 不包含
*/
boolean containsValue(Object value);
/** 根据key获取value; 如果没有返回为null */
V get(Object key);
/*********************** Map 修改业务 **************************/
/**
* 新增键值对
*
* @param key 要新增的key
* @param value 要新增的value
* @return 返回key关联的前一个值,如果没有则返回null
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
* @throws IllegalArgumentException 非法参数异常
*/
V put(K key, V value);
/**
* 删除map集合中对应的key-value 键值对
*
* @param key
* @return 返回key前一个映射的值
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
*/
V remove(Object key);
/*********************** Map 批量业务 **************************/
/**
* 新增指定的元素集
*
* @param m 要新增的map元素集合
* @throws UnsupportedOperationException 不支持操作异常
* @throws ClassCastException 类型转换异常
* @throws NullPointerException 空指针异常
* @throws IllegalArgumentException 非法参数异常
*/
void putAll(Map<? extends K, ? extends V> m);
/**
* 清空Map集合
* @throws UnsupportedOperationException 不支持操作异常
*/
void clear();
/*********************** Map的视图业务 **************************/
/**
* 获取 key 的所有元素,并以Set形式进行返回;
*/
Set<K> keySet();
/**
* 获取 values 的所有元素,并以Collection形式进行返回
*/
Collection<V> values();
/**
* 获取 key-value 的所有元素,并以Set形式进行返回;类型是Map.Entry
*/
Set<Map.Entry<K, V>> entrySet();
/*********************** Map 的映射业务 Entry **************************/
/**
* map 是一个 key-value 的映射集合;映射业务标准定义由Entry实现;
* Entry 中文名称为“实体”的意思;也就是Map的元素表现就是 Entry ;
* Entry 里面包含着 key与value ;
* 那为什么不直接定义为一个 实体类 calss Entry, 然后指定定义属性key,value,再定义getting与setting呢?
* 首先,接口的作用是什么?接口的作用是提供标准。没错interface Entry 是为了提供映射业务实现的标准;从而不限制 Entry的具体实现方式;具体的子类可以根据自己的特性进行实现;
* 如果在定义Map 接口的时候,就将Entry写成一个实体类,就意味着Map的Entry实现方式就只有一种固定的,可能无法满足不同子类的需求
* @see Map#entrySet()
* @since 1.2
*/
interface Entry<K, V> {
/** 获取 key */
K getKey();
/** 获取 value */
V getValue();
/** 设置 value */
V setValue(V value);
/** 比较Entry是否相同 */
boolean equals(Object o);
/** 获取hashCode */
int hashCode();
/**
* @return 根据key进行自然比较
* @see Comparable
* @since 1.8
*/
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());
}
/**value
* @return 根据value进行自然比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* @return 根据key进行比较器进行比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* @return 根据value进行比较器进行比较
* @see Comparable
* @since 1.8
*/
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());
}
/**
* 复制一个Map.Entry 实体
* @since 17
*/
@SuppressWarnings("unchecked")
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());
}
}
}
// Comparison and hashing
boolean equals(Object o);
int hashCode();
/*********************** Map 的 Defaultable 方法 **************************/
/**
* 返回指定key映射的值,如果key没有映射的值则返回defaultValue值
*
* @param key 指定的key
* @param defaultValue 默认值
* @since 1.8
*/
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
/**
* 对此Map中的每个映射实体类执行给定的操作
* @since 1.8
*/
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);
}
}
/**
* 将每个映射实体类的值替换为调用给定方法的结果;直到所有的表项都被处理完为止
* @since 1.8
*/
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
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);
}
// ise thrown from function is not a cme.
v = function.apply(k, v);
try {
entry.setValue(v);
} catch (IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
}
}
/**
* 如果当前key没有映射的value;则将指定的value进行绑定;否则不处理
* @since 1.8
*/
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
/**
* key所关联的value;必须和传入的value一致才能被删除
* @since 1.8
*/
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;必须和传入的oldValue一致才能被newValue所替换
* @since 1.8
*/
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所关联的value;必须和传入的value一致才能被替换
* @since 1.8
*/
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
/**
* 如果指定的key所映射的value为空,则尝试将mappingFunction 的value与key进行关联映射
*
* @since 1.8
*/
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
/**
* 如果指定key的值存在且非空,则尝试将remappingFunction的value与key进行关联映射
* @since 1.8
*/
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}
/**
* remappingFunction 的value 如果不为空,则于key进行关联映射,
* 如果key所关联的value != null,则删除key; 否则key于remappingFunction 的value 进行关联映射
*/
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
/**
* @since 1.8
*/
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if (newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
/*********************** Map 不可修改业务 **************************/
/**
* 返回包含0映射实体的不可修改映射Map
* @since 9
*/
@SuppressWarnings("unchecked")
static <K, V> Map<K, V> of() {
return (Map<K,V>) ImmutableCollections.EMPTY_MAP;
}
/**
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1) {
return new ImmutableCollections.Map1<>(k1, v1);
}
/**
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
return new ImmutableCollections.MapN<>(k1, v1, k2, v2);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* @since 9
*/
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);
}
/**
* 返回一个不可修改的映射,其中包含从给定项提取的键和值
* @since 9
*/
@SafeVarargs
@SuppressWarnings("varargs")
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
if (entries.length == 0) { // implicit null check of entries array
@SuppressWarnings("unchecked")
var map = (Map<K,V>) ImmutableCollections.EMPTY_MAP;
return map;
} else if (entries.length == 1) {
// implicit null check of the array slot
return new ImmutableCollections.Map1<>(entries[0].getKey(),
entries[0].getValue());
} else {
Object[] kva = new Object[entries.length << 1];
int a = 0;
for (Entry<? extends K, ? extends V> entry : entries) {
// implicit null checks of each array slot
kva[a++] = entry.getKey();
kva[a++] = entry.getValue();
}
return new ImmutableCollections.MapN<>(kva);
}
}
/**
* 返回一个包含给定键和值的不可修改的
* @see Map#ofEntries Map.ofEntries()
* @since 9
*/
static <K, V> Entry<K, V> entry(K k, V v) {
// KeyValueHolder checks for nulls
return new KeyValueHolder<>(k, v);
}
/**
* 复制Map
* @since 10
*/
@SuppressWarnings({"rawtypes","unchecked"})
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]));
}
}
}
二,AbstractMap
java.util.AbstractMap 是 Java 集合框架中的一个抽象类,它为实现 Map 接口提供了骨架实现。AbstractMap 类的目的是简化自定义映射实现的创建过程,减少需要实现的代码量。它提供了一些默认实现,并声明了一些需要子类具体实现的方法。
2.1 AbstractMap 构造方法
protected AbstractMap() {}
2.2 AbstractMap 查询业务
2.2.1 size()
public int size() {
return entrySet().size();
}
2.2.2 isEmpty()
public boolean isEmpty() {
return size() == 0;
}
2.2.3 containsValue(value)
/**
* 是否包含指定的value
* true - 包含 | false - 不包含
*/
public boolean containsValue(Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();
// 如果比较包含value的内容是 null;
if (value==null) {
while (i.hasNext()) {
// 则进行遍历map,逐个获取value是否有 null; 有则返回true
Entry<K,V> e = i.next();
if (e.getValue()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
// 进行遍历map,逐个获取value是否与传入的value相同; 相同则返回true
if (value.equals(e.getValue()))
return true;
}
}
return false;
}
2.2.4 containsKey(key)
/**
* 是否包含指定的key
* true - 包含 | false - 不包含
*/
public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
// 如果比较包含key的内容是 null;
if (key==null) {
// 则进行遍历map,逐个获取key是否有 null; 有则返回true
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
// 进行遍历map,逐个获取key是否与传入的key相同; 相同则返回true
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}
2.2.5 get(key)
根据 key获取指定的value
public V get(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return e.getValue();
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return e.getValue();
}
}
return null;
}
2.3 AbstractMap 修改(写)业务
2.3.1 put(key,value)
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
2.3.2 remove(key)
AbstractMap 提供默认删除的业务逻辑骨架,这样做的目的减少了代码量,并提供一些默认实现方法
/**
* 根据 key 进行删除;并返回key对应value
*
*/
public V remove(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
Entry<K,V> correctEntry = null;
// 如果传入的key 为 null
if (key==null) { // 则通过迭代器迭代获取 为null key
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
correctEntry = e;
}
// 如果传入的 key 不为 null
} else { // // 则通过迭代器迭代获取与传入key相同的key
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
correctEntry = e;
}
}
V oldValue = null;
if (correctEntry !=null) { // 不为空,意味着传入的key 值在map中有对应的entry
oldValue = correctEntry.getValue();
i.remove(); // 进行删除
}
return oldValue; // 返回value
}
2.4 AbstractMap 批量业务
2.4.1 putAll(m)
public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
put(e.getKey(), e.getValue());
}
2.4.2 clear()
public void clear() {
entrySet().clear();
}
2.5 AbstractMap 视图业务
transient Set<K> keySet;
transient Collection<V> values;
2.5.1 keySet()
在Map 里面 视图的概念是什么?其实就是以集合的形式展现。这些视图允许我们查看、操作和迭代 Map 的内容;而内容又进行分类管理。分为 KeySet (key 的集合),values (value的集合),entrySet (Entry 映射实体类的集合)
在 AbstractMap 抽象类里面都默认提供 keySet(), values(), entrySet() 视图业务逻辑骨架;像获取key 的集合;就是一个Set集合;原因很简单,key不能重复;所以当然用Set进行接收;不管里面都是调用 AbstractMap 抽象类自己业务方法;意味着具体实现由子类来决定
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new AbstractSet<K>() {
public Iterator<K> iterator() {
return new Iterator<K>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public K next() {
return i.next().getKey();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object k) {
return AbstractMap.this.containsKey(k);
}
};
keySet = ks;
}
return ks;
}
2.5.2 values()
public Collection<V> values() {
Collection<V> vals = values;
if (vals == null) {
vals = new AbstractCollection<V>() {
public Iterator<V> iterator() {
return new Iterator<V>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
values = vals;
}
return vals;
}
2.5.3 entrySet()
public abstract Set<Entry<K,V>> entrySet();
2.6 Comparison & hashing
2.6.1 equals(o)
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map<?, ?> m))
return false;
if (m.size() != size())
return false;
try {
for (Entry<K, V> e : entrySet()) {
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key) == null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}
2.6.2 hashCode()
public int hashCode() {
int h = 0;
for (Entry<K, V> entry : entrySet())
h += entry.hashCode();
return h;
}
2.7 AbstractMap 其他业务
2.7.1 toString()
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
2.7.2 clone()
protected Object clone() throws CloneNotSupportedException {
AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
result.keySet = null;
result.values = null;
return result;
}
2.7.3 eq(o1, o2)
private static boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
2.8 AbstractMap 映射实体Entry接口实现
2.8.1 简单映射实体
public static class SimpleEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
@java.io.Serial
private static final long serialVersionUID = -8499721149061103585L;
@SuppressWarnings("serial") // Conditionally serializable
private final K key;
@SuppressWarnings("serial") // Conditionally serializable
private V value;
/** 通过构造器传入 key和value */
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
/** 通过Entry接口创建一个SimpleEntry*/
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
public K getKey() { return key; }
public V getValue() { return value; }
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
public boolean equals(Object o) {
return o instanceof Map.Entry<?, ?> e
&& eq(key, e.getKey())
&& eq(value, e.getValue());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() { return key + "=" + value; }
}
2.8.2 不可修改的映射实体
不可修改的 Entry 实体,只支持读取数据的操作,像getting,而setting之类则不支持操作;实现的方式就是在写操作方法里面直接抛 UnsupportedOperationException 不支持操作异常;这样就达到不可修改的目的;这里不可修改指定的Entry 的实体内容;而非引用;
public static class SimpleImmutableEntry<K,V>
implements Entry<K,V>, java.io.Serializable
{
@java.io.Serial
private static final long serialVersionUID = 7138329143949025153L;
@SuppressWarnings("serial") // Not statically typed as Serializable
private final K key;
@SuppressWarnings("serial") // Not statically typed as Serializable
private final V value;
/**
* 通过传入的key和value创建一个SimpleImmutableEntry
*/
public SimpleImmutableEntry(K key, V value) {
this.key = key;
this.value = value;
}
/** 通过 Entry 接口创建一个SimpleImmutableEntry */
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
public K getKey() { return key; }
public V getValue() { return value; }
public V setValue(V value) {
throw new UnsupportedOperationException();
}
public boolean equals(Object o) {
return o instanceof Map.Entry<?, ?> e
&& eq(key, e.getKey())
&& eq(value, e.getValue());
}
public int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
}
三,AbstractImmutableMap
java.util.ImmutableCollections.AbstractImmutableMap 是 Java 中一个内部抽象类,专门用于表示不可变的映射(Map)。不可变映射是指一旦创建,其内容就不能被修改的映射。这种不可变特性在多线程环境中非常有用,因为它们本质上是线程安全的。
这个类是在 ImmutableCollections 工具类当中,从名称也可以得知这是专门用来处理不可修改集合的。包括List, Set, Map;这些接口都有对应的不可修改集合;
不能发现 AbstractImmutableMap 抽象类所以有关写操作调用的都是 uoe();
uoe()方法就是直接抛出一个 UnsupportedOperationException 不支持操作异常;表示不支持该操作,通过这样的形式来实现集合不可修改的特性;因为只要一旦调用put, remove等等操作就是抛 UnsupportedOperationException 不支持操作异常;
3.1 Map1 & MapN
不管怎么说 AbstractImmutableMap 终究只是对不可修改提供一个抽象类,提供不可修改的基本业务骨架;就是通过调用 uoe();抛 UnsupportedOperationException 异常实现。
具体的子类有哪些?在Java里面提供两种一个 Map1; 一个是 MapN;
3.2 Map1 和 MapN 的区别
Map1: 适用于仅包含一个键值对的不可变映射。它是为单元素映射进行特殊优化的实现。
MapN: 适用于包含多个键值对的不可变映射。它是为多元素映射设计的实现。
【内部实现】
Map1: 由于只包含一个键值对,其内部实现非常简单。它直接存储键和值,没有复杂的数据结构。
MapN:适用于多个键值对,因此其内部实现要复杂一些,使用了更复杂的数据结构(如数组)来存储多个键值对
【性能优化】
Map1
: 由于只处理一个键值对,操作非常快速,内存占用也非常小。MapN
: 虽然支持多个键值对,但仍然进行了优化,以确保在处理少量键值对时具有较好的性能。