Java-01-基础篇 Java集合-01-Map(源码)

news2024/11/24 5:21:21

目录

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1831571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

修改以太网卡mac地址

原生以太网卡与PCIe以太网卡 以Intel 原生以太网卡与PCIe以太网卡为例&#xff1a; Intel原生以太网卡和PCIe以太网卡在系统中实现网络连接时&#xff0c;涉及到与系统总线&#xff08;如PCIe总线&#xff09;的连接方式和性能差异。 Intel 原生以太网卡 定义&#xff1a;所…

【Python】Redis数据库

Redis数据库 Unit01一、Redis1.1 概述1.2 安装1.3 Redis-cli1.4 数据类型1.5 字符处理1.6 键的命名规则 二、通用命令三、字符串(String)3.1 概述3.2 常用命令3.3 应用场景 四、列表(List)4.1 概述4.2 常用命令 五、集合(SET)5.1 概述5.3 常用命令 六、有序集合6.1 概述6.2 常用…

揭秘“湖仓一体”——Flink+Paimon+StarRocks,打造实时分析新纪元

1.湖仓一体 数据湖仓是 Flink 流批一体发挥重要作用的场景,使用 Flink Paimon starRocks 来构建湖仓一体数据分析. Apache Paimon 是一个专为实时数据处理而设计的湖表格式&#xff0c;它最大的亮点是使用了 LSM Tree 技术。与 Hudi 相比&#xff0c;Paimon 在更新插入&…

日本新入管法通过:2027年起实施[育成就劳]制度,新制度更适合外国劳工在日本工作和生活!

最近&#xff0c;日本新入管法&#xff1a;新的育成就业制度预计将在2027年开始实施&#xff0c;而1993年开始的旧的技能实习制度将被废除。 新制度的主要内容 新制度的目的是解决日本国内的劳动力不足问题&#xff0c;确保有足够的劳动者。表示&#xff1a;“为了让日本成为…

jrt从量变到质变

又是一个加班的周末&#xff0c;上周把台式机代码和数据库环境弄好了&#xff0c;这周进行大数据测试&#xff0c;直接把标本、标本医嘱、报告、报告结果、药敏结果等数据插入到1亿的规模&#xff0c;跑了一天一夜插入了5000多万个标本&#xff0c;后面接着补剩下的到一亿。 演…

使用 Cheerio 和 Node.js 进行网络搜刮 2024

Web scraping 是一种强大的技术&#xff0c;用于从网站提取数据&#xff0c;广泛应用于数据分析、市场研究和内容聚合。截至2024年&#xff0c;利用 Cheerio 和 Node.js 进行 web scraping 仍然是一种流行且高效的方法。本文将深入探讨使用 Cheerio 和 Node.js 进行 web scrapi…

交易方法论

如何复盘,复盘哪些内容&#xff1a; 1复盘指数 2复盘板块 3复盘个股 4复盘涨停板 5跌停板 6自选股 1复盘新闻 2国家大势 3行业大势 4公司大事 5资金流向 6龙虎榜 板块强度标准 板块内至少有5只涨停板 板块连续资金流入超过3天 板块有5只以上走漂亮上升趋势 一次性关注方向不…

LangChain-ChatGLM本地搭建|报错合集(win10)

安装过程 1. 创建虚拟环境 conda create -n langchain-chatglm python3.10 conda activate langchain-chatglm2. 部署 langchain-ChatGLM git clone https://github.com/imClumsyPanda/langchain-ChatGLMpip3 install -r requirements.txt pip3 install -U gradio pip3 inst…

太速科技-FMC213V3-基于FMC兼容1.8V IO的Full Camera Link 输入子卡

FMC213V3-基于FMC兼容1.8V IO的Full Camera Link 输入子卡 一、板卡概述 该板卡为了考虑兼容1.8V电平IO&#xff0c;适配Virtex7&#xff0c;Kintex Ultrascale&#xff0c;Virtex ultrasacle FPGA而特制&#xff0c;如果要兼容原来的3.3V 也可以修改硬件参数。板卡支持1路…

【自动驾驶】ROS小车系统介绍

文章目录 小车组成轮式运动底盘的组成轮式运动底盘的分类轮式机器人的控制方式感知传感器ROS决策主控ROS介绍ROS的坐标系ROS的单位机器人电气连接变压模块运动底盘的电气连接ROS主控与传感器的电气连接运动底盘基本组成电池电机控制器与驱动器控制器与运动底盘状态数据&#xf…

记录第一次突发情况

项目场景&#xff1a; 这台云服务器主要是我学习在用&#xff0c;也不是很大&#xff0c;2核2g3M40G硬盘。 在这台服务器上&#xff0c;我主要使用了docker并且把所有的东西&#xff0c;都通过docker安装&#xff0c;比如MySQL&#xff0c;redis&#xff0c; elasticsearch。 …

视频合成渲染服务解决方案,数字人+PPT+视频云剪辑

在金融理财领域&#xff0c;一个生动、直观、专业的视频&#xff0c;往往能够在海量信息中脱颖而出&#xff0c;帮助客户更好地理解产品、把握市场动态。然而&#xff0c;传统的视频制作方式往往周期长、成本高、难以适应快速变化的市场需求。 美摄科技&#xff0c;作为行业领…

CANape使用问题记录

CANape使用问题记录 1、添加变量后无法开启测量 1、添加变量后无法开启测量 点击开启测量后&#xff0c;出现以下对话框&#xff1a; 解决方法&#xff1a; 添加新变量后&#xff0c;修改变量测量配置&#xff1b; 改为polling&#xff0c; 1000&#xff0c;即采用轮训的方法…

收入增长,再进一步丨用友BIP收入云大消费品行业收入管理联合解决方案正式发布

随着数智化时代的来临&#xff0c;消费品行业对于收款到收入侧的管理需求日益增强&#xff0c;对管理的精细度和时效性要求也越来越高。传统的收入管理模式已难以满足企业快速变化的市场需求。如何精准地预测收入、优化收入结构、提高收入管理质量&#xff0c;以及实现收入管理…

雪花算法和UUID

目录 雪花算法概念优点和不足优点:缺点:解决方案代码示例 UUID优点与不足优点不足 两种算法的比较应用场景区别 雪花算法 概念 雪花算法是一个分布式id生成算法&#xff0c;它生成的id一般情况下具有唯一性。由64位01数字组成&#xff0c;第一位是符号位&#xff0c;始终为0。…

Kubernetes集群中如何利用北极星因果指标设置正确的POD规格——CPU篇

在 Kubernetes 容量规划中&#xff0c;追求的是集群的稳定性和资源使用效率之间的平衡&#xff1a; 资源分配过多会造成浪费。 资源分配过少则会导致用户请求时延上升&#xff0c;影响集群的稳定性。 背景 公众号之前翻译了一篇 Sysdig 的文章&#xff0c;Kubernetes 容量规…

玩转nRF52840-DK开发套件(2)

介绍如何在Windows操作系统上使用Arm Keil MDK。Arm Keil MDK附带Arm C/C编译器和Vision集成开发环境&#xff08;IDE&#xff09;&#xff0c;以及所有nRF5SDK的版本提供了现成的Keil项目。 1. 安装最新的 nRF5 SDK. 链接&#xff1a;nRF5 SDK - nordicsemi.com 点击Download&…

泰迪智能科技董事长张良均荣获“2024年广东软件风云榜新锐企业家”

6月13日&#xff0c;在广州举办2024年粤港澳软件产业高质量发展大会、第十二届粤港云计算大会暨第七届粤港澳ICT大会。大会以“培育信息技术新质生产力&#xff0c;打造粤港澳发展创新引擎”为主题&#xff0c;研讨基础软件、云计算、人工智能等新一代技术的新态势、新应用&…

14.编写自动化测试(上)

标题 一、如何编写测试1.1 一些概念1.2 测试函数剖析1.3 使用assert!宏检查结果1.4 使用assert_eq!和assert_ne!宏来测试相等1&#xff09; assert_eq!2&#xff09; assert_ne! 1.5 使用 should_panic 检查 panic 二、将 Result<T, E> 用于测试 一、如何编写测试 1.1 一…

解决外网404:清除DNS缓存并配置host主机使用知名公共DNS服务

在 Windows 上清除/刷新 DNS 缓存 对于所有Windows版本&#xff0c;清除DNS缓存的过程都是相同的。你需要使用管理员权限打开命令提示符并运行ipconfig /flushdns。 浏览器清除DNS缓存 大多数现代的Web浏览器都有一个内置的DNS客户端&#xff0c;以防止每次访问该网站时…