目录
一,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
: 虽然支持多个键值对,但仍然进行了优化,以确保在处理少量键值对时具有较好的性能。