HashMap 源码分析

-- 注:HashMap被重新写到自定义的com.test.util包下,并删减修改了部分内容以保证它可以测试,并添加了注释 --

package com.test.util;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMap<K, V> implements Map<K, V>, Cloneable, Serializable {

    /******************************** 成员变量-start ********************************/
    transient Node<K, V>[] table;   // 存储key-value映射
    transient int modCount;         // 记录被修改的次数
    transient int size;             // HashMap存储的映射的数目
    int threshold;                  // 扩容时的临时阈值
    final float loadFactor;         // hash表的加载因子,默认也是0.75
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默认初始化容量大小为16
    static final float DEFAULT_LOAD_FACTOR = 0.75f;     // 加载因子
    static final int MAXIMUM_CAPACITY = 1 << 30;        // 默认最大容量,即Integer最大值的一半
    static final int TREEIFY_THRESHOLD = 8;             // 转化为红黑树的阈值,至少为8
    transient Set<Map.Entry<K, V>> entrySet;             // 存储所有的键值对映射的集合
    // 以下为AbstractMap类中的属性
    transient volatile Set<K> keySet;        // 所有key的视图
    transient volatile Collection<V> values; // 所有value的视图
    /******************************** 成员变量-end ***********************************/


    /******************************** 构造函数-start ********************************/
    public HashMap(int initialCapacity) {
        // 构造指定容量和默认加载因子(0.75)
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // 设置hash表的默认加载因子
    }

    public HashMap(int initialCapacity, float loadFactor) {
        // 校验初始化大小是否大于0,是否小于最大默认容量;加载因子是否是合法数字并且大于0
        if (initialCapacity < 0) {
            throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
        }
        if (initialCapacity > MAXIMUM_CAPACITY) {
            initialCapacity = MAXIMUM_CAPACITY;
        }
        if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
            throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
        }
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity); // 根据初始化容量计算阈值大小
    }

    public HashMap(Map<? extends K, ? extends V> m) {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        putMapEntries(m, false);
    }
    /******************************** 构造函数结束-end ***********************************/


    /******************************** put(K, V)方法-start ********************************/
    @Override
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        putMapEntries(m, true);
    }

    /**
     * @param hash         key的hash值
     * @param key          key
     * @param value        value
     * @param onlyIfAbsent 是否不替换掉旧值:true并且旧值不为空:不替换; false:替换
     * @param evict        子类插入时的判断:是否移除
     * @return 如果存在则返回以前的value,否则返回当前的value
     */
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
        // 1.判断节点table的是否为空或者长度是否为0,如果是则重置节点table的大小
        Node<K, V>[] tab;
        Node<K, V> p;
        int n, i;
        if ((tab = table) == null || (n = tab.length) == 0) {
            n = (tab = resize()).length;
        }
        // 2.如果数组的位置为空,则创建一个新节点存放数据
        if ((p = tab[i = (n - 1) & hash]) == null) {//n最大值为16,(n-1)&任何数的结果都会小于16(最大是15)
            tab[i] = new Node(hash, key, value, null);
        } else {
            // 3.此处是数组的位置已经存在数据,再插入数据的逻辑
            Node<K, V> e;
            K k;
            // 3.1 当前插入的key和Node[]中的key相同时,即key已存在,则替换此映射的value(后面会有替换操作)
            if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) {
                e = p;
            } else if (p instanceof TreeNode) {
                // 3.2 如果节点属于红黑树树,则通过树来存放节点
                e = ((TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value);
            } else {
                // 3.2 如果节点不存在于Node[]中且节点不是红黑树节点,遍历所有的链表节点
                for (int binCount = 0; ; ++binCount) {
                    // 如果p是最后一个节点,则跳出循环
                    if ((e = p.next) == null) {
                        p.next = new Node<>(hash, key, value, null);
                        // 如果插入前最后一个节点的位置大于等于7(即插入后大于等于8),则通过红黑树的方式进行处理
                        if (binCount >= TREEIFY_THRESHOLD - 1) {
                            // 替换给定哈希的索引处bin中的所有链接节点,除非表太小,在这种情况下会调整大小。
                            treeifyBin(tab, hash);
                        }
                        break;
                    }
                    // 如果此key已在链表中存在,则跳出循环
                    if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {
                        break;
                    }
                }
            }
            // 替换掉以前的值
            if (e != null) {
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null) {
                    e.value = value;
                }
                // 在访问过节点之后的操作
                afterNodeAccess(e);
                // 返回以前的值
                return oldValue;
            }
        }

        // 4.判断(当前数据量的大小+1)是否>容量*加载因子,如果大于则重新扩容
        ++modCount; //此属性防止map中的映射被非法更改
        if (++size > threshold) {
            resize();
        }

        // 5.在插入之后的处理:此处交由子类实现
        afterNodeInsertion(evict);

        return null;
    }

    // 存放整个map
    final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
        int s = m.size();
        if (s > 0) { // 如果存储的map有值则进行存储,否则跳过
            if (table == null) {
                float ft = ((float) s / loadFactor) + 1.0F;  //根据加载因子计算的的大小
                int t = ((ft < (float) MAXIMUM_CAPACITY) ? (int) ft : MAXIMUM_CAPACITY);
                if (t > threshold) {
                    threshold = tableSizeFor(t);
                } //求阈值
            } else if (s > threshold) {
                resize();   //如果传入的map的大小超过了阈值,则对新map进行再扩容
            }
            // 循环遍历当前传入的map,并依次将其中的键值对存放到新的map中
            for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
                K key = e.getKey();
                V value = e.getValue();
                putVal(hash(key), key, value, false, evict);
            }
        }
    }
    /******************************** put(K, V)方法-end ***********************************/


    /******************************** get(Object key)方法-start ********************************/
    @Override
    public V get(Object key) {
        Node<K, V> e;
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }
    // 获取node节点
    final Node<K, V> getNode(int hash, Object key) {
        Node<K, V>[] tab;   // 原map中的table
        Node<K, V> first, e;// first为通过hash计算的得出的Node[]中的元素,e为遍历map时的临时元素
        int n;              // 原map的大小
        K k;                // k为map中存在的key
        // 如果map不为空且通过hash值可以在Node[]中找到首元素
        if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) {
            // 先校验首元素的hash和key是否符合条件,符合则返回
            if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) {
                return first;
            }
            // 如果首元素不符合,则遍历此首元素以下的链表,找出hash相同且key相同的元素
            if ((e = first.next) != null) {
                // 如果首元素下的next元素的类型是红黑树类型,则按照红黑树的查找方式查找
                if (first instanceof TreeNode) {
                    return ((TreeNode<K, V>) first).getTreeNode(hash, key);
                }
                // 如果首元素下的next元素不是红黑树类型,则循环遍历,找出hash相同且key相同的元素
                do {
                    if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {
                        return e;
                    }
                } while ((e = e.next) != null);
            }
        }
        return null;
    }
    /******************************** get(Object key)方法-end ********************************/


    /******************************** remove(Object key)方法-start ********************************/
    public V remove(Object key) {
        Node<K, V> e;
        return (e = removeNode(hash(key), key, null, false, true)) == null ?
                null : e.value;
    }
    /**
     * 移除节点
     *
     * @param hash       key的再hash值
     * @param key        键
     * @param value      值
     * @param matchValue 如果为false则不比较value就进行移除
     * @param movable    红黑树是否可移动
     * @return 返回被删除的节点
     */
    final Node<K, V> removeNode(int hash, Object key, Object value,
                                boolean matchValue, boolean movable) {
        Node<K, V>[] tab;//当前map的Node表
        Node<K, V> p;    //Node[]中的元素:值为tab[(n-1)&hash]
        int n, index;   //n:Node表的长度,index:根据hash求出的Node[]的下标
        // 如果元素的hash值可以在Node[]中查询到则进行移除操作,否则跳过(不存在)
        if ((tab = table) != null && (n = tab.length) > 0 &&
                (p = tab[index = (n - 1) & hash]) != null) {
            Node<K, V> node = null, e;
            K k;
            V v;
            if (p.hash == hash &&   //如果首元素符合,则会移除首元素,否则由首元素向下遍历
                    ((k = p.key) == key || (key != null && key.equals(k)))) {
                node = p;
            } else if ((e = p.next) != null) {
                // 判断节点是不是红黑树节点,如果是则通过红黑树的方式查询,否则循环遍历
                if (p instanceof TreeNode) {
                    node = ((TreeNode<K, V>) p).getTreeNode(hash, key);
                } else {
                    do {
                        if (e.hash == hash &&
                                ((k = e.key) == key || (key != null && key.equals(k)))) {
                            node = e;
                            break;
                        }
                        p = e;//将待删除元素的pre元素赋值给p
                    } while ((e = e.next) != null);
                }
            }
            // 移除操作处理:matchValue为false意味着不再比较value,否则会比较value
            if (node != null && (!matchValue || (v = node.value) == value ||
                    (value != null && value.equals(v)))) {
                // 如果节点属于红黑树节点,则通过红黑树的方式移除
                if (node instanceof TreeNode) {
                    ((TreeNode<K, V>) node).removeTreeNode(this, tab, movable);
                }
                // 如果节点是Node[]中的数据,则将它的next节点上移即可
                else if (node == p) {
                    tab[index] = node.next;
                }
                // 如果节点是普通节点(非首节点非红黑树节点),则将node的上一个元素的next指向node.next
                else {
                    p.next = node.next;
                }
                // 数量减一,修改次数加一,然后进行移除后的操作,最后返回删除的元素
                ++modCount;
                --size;
                afterNodeRemoval(node);
                return node;
            }
        }
        return null;
    }
    /******************************** remove(Object key)方法-end ********************************/


    /******************************** 其他方法-start ********************************/
    // 求map中键值对数目
    public int size() {
        return size;
    }

    // 判断map键值对数量是否为空
    public boolean isEmpty() {
        return size == 0;
    }

    // 判断map中是否存在此key
    public boolean containsKey(Object key) {
        return getNode(hash(key), key) != null;
    }

    // 判断map中是否存在此value
    public boolean containsValue(Object value) {
        Node<K, V>[] tab;
        V v;
        // 如果Node表不为空并且有数据则进行循环遍历查询
        if ((tab = table) != null && size > 0) {
            // 遍历数组
            for (int i = 0; i < tab.length; ++i) {
                // 遍历数组下的链表,对链表逐个遍历,如果找到则返回true
                for (Node<K, V> e = tab[i]; e != null; e = e.next) {
                    if ((v = e.value) == value
                            || (value != null && value.equals(v)))
                        return true;
                }
            }
        }
        return false;
    }

    // 清空map中所有的元素
    public void clear() {
        Node<K, V>[] tab;
        modCount++;
        if ((tab = table) != null && size > 0) {
            // 将大小置为0,Node表中的数据逐个全部置为null
            size = 0;
            for (int i = 0; i < tab.length; ++i) {
                tab[i] = null;
            }
        }
    }

    // 所有键的视图:包含了所有的key
    public Set<K> keySet() {
        Set<K> ks;
        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
    }

    // 所有键的视图:包含了所有的value
    public Collection<V> values() {
        Collection<V> vs;
        return (vs = values) == null ? (values = new Values()) : vs;
    }

    // 所有key-value映射的视图:单独包含所有的key-value映射
    public Set<Map.Entry<K, V>> entrySet() {
        Set<Map.Entry<K, V>> es;
        return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
    }

    // 克隆当前map
    @SuppressWarnings("unchecked")
    public Object clone() {
        HashMap<K,V> result;
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
        result.reinitialize();  // 重置所有初始化属性
        // 存放当前map
        result.putMapEntries(this, false);
        return result;
    }
    /******************************** remove(Object key)方法-end ********************************/


    /******************************** jdk8新特性方法-start ********************************/
    // 根据key获取value,如果获取不到,则返回传递的defaultValue
    public V getOrDefault(Object key, V defaultValue) {
        Node<K,V> e;
        return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
    }

    // 存储映射:如果以前的value为空,则存储,如果以前的值为空,则不存储
    public V putIfAbsent(K key, V value) {
        return putVal(hash(key), key, value, true, true);
    }

    // 根据key,value移除节点:如果移除的key-value存在,则返回true,否则返回false
    public boolean remove(Object key, Object value) {
        return removeNode(hash(key), key, value, true, true) != null;
    }

    // 根据key替换以前的value值
    public V replace(K key, V value) {
        Node<K,V> e;
        if ((e = getNode(hash(key), key)) != null) {
            V oldValue = e.value;
            e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
        return null;
    }

    // 根据key替换以前的value值:如果和传递的key-oldValue相同,则map的value会被newValue替换;否则不替换
    public boolean replace(K key, V oldValue, V newValue) {
        Node<K,V> e; V v;
        if ((e = getNode(hash(key), key)) != null &&
                ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
            e.value = newValue;
            afterNodeAccess(e);
            return true;
        }
        return false;
    }

    //public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {...}
    //public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {...}
    //public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {...}
    //public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {...}
    //public void forEach(BiConsumer<? super K, ? super V> action) {...}
    //public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {...}
    /******************************** jdk8新特性方法-end ********************************/


    /******************************** 其他被调用的方法-start ********************************/
    void afterNodeInsertion(boolean evict) {
    }  //插入之后的处理操作

    void afterNodeAccess(Node<K, V> p) {
    }      //访问之后的处理操作

    void afterNodeRemoval(Node<K, V> p) {
    }      //删除之后的处理操作

    // 重置到初始化状态,被clone方法和readObject方法调用
    void reinitialize() {
        table = null;
        entrySet = null;
        keySet = null;
        values = null;
        modCount = 0;
        threshold = 0;
        size = 0;
    }

    // 求key的hashCode
    static final int hash(Object key) {
        int h;  //再求一次hash,尽量扰乱hash值,使得数据均匀分布
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    // Node节点:存储key-value
    static class Node<K, V> implements Map.Entry<K, V> {
        int hash;   // 存储hash值
        K key;      // 存储key
        V value;    // 存储value
        Node<K, V> next;// 存储下一个节点

        Node(int hash, K key, V value, Node<K, V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }
    }

    // 初始化或加倍表大小。如果为空,则根据字段阈值中保留的初始容量目标进行分配。否则,在新表中以2的幂次偏移量移动。
    Node<K, V>[] resize() {
        Node<K, V>[] oldTab = table;
        int oldCap = (oldTab == null) ? 0 : oldTab.length;    // 以前的容量
        int oldThr = threshold; // 以前的阈值
        int newCap, newThr = 0;     // 新的容量,新的阈值

        // 设置阈值,初始化大小
        if (oldCap > 0) {
            // 如果原来的容量大于0
            // 判断是否大于MAXIMUM_CAPACITY,如果大于等于默认的最大的容量,则设置阈值为Integer.MAX_VALUE
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            } else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) {
                // 如果以前的容量大于默认的初始化容量,而且以前容量的两倍小于默认最大容量,则设置阈值为以前容量的两倍
                newThr = oldThr << 1;
            }
        } else if (oldThr > 0) {
            // 如果table为空并且阈值大于0,则新的容量为以前的阈值
            newCap = oldThr;
        } else {
            // 第一次插入:设置Node数组默认容量,设置下一次阈值大小(0.75*16=12)
            newCap = DEFAULT_INITIAL_CAPACITY;
            newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }

        // 如果阈值为0,则重新设置阈值
        if (newThr == 0) {
            float ft = (float) newCap * loadFactor;  //通过加载因子扩容的大小
            // 如果新的容量小于默认最大容量并且ft也小于默认最大容量,则取ft的值,否则取Integer.MAX_VALUE
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ? (int) ft : Integer.MAX_VALUE);
        }
        threshold = newThr; //设置下一次的阈值大小

        // 新建一个Node数组
        Node<K, V>[] newTab = (Node<K, V>[]) new Node[newCap];
        table = newTab;

        // 如果以前的table不是空,找出链表中的最后一个元素
        if (oldTab != null) {
            for (int j = 0; j < oldCap; j++) {
                Node<K, V> e;
                // 设置Node数组根节点
                if ((e = oldTab[j]) != null) {
                    oldTab[j] = null;
                    if (e.next == null) {
                        // 子节点为空(即自己是根节点),则直接赋值给新的Node数组的相应位置
                        newTab[e.hash & (newCap - 1)] = e;
                    } else if (e instanceof TreeNode) {
                        // 将树容器中的节点拆分为较低和较高的树容器,如果现在太小,则取消搜索。仅从resize调用;
                        ((TreeNode<K, V>) e).split(this, newTab, j, oldCap);
                    } else {
                        Node<K, V> loHead = null, loTail = null;
                        Node<K, V> hiHead = null, hiTail = null;
                        Node<K, V> next;
                        do {
                            // 此循环中,当e.next==null时,即e没有子节点
                            next = e.next;
                            // 如果(e.hash & oldCap) == 0则表示它是链表的元素,否则它是尾元素
                            if ((e.hash & oldCap) == 0) {
                                if (loTail == null) {
                                    loHead = e;
                                } else {
                                    loTail.next = e;
                                }
                                loTail = e;
                            } else {
                                if (hiTail == null) {
                                    hiHead = e;
                                } else {
                                    hiTail.next = e;
                                }
                                hiTail = e;
                            }
                        } while ((e = next) != null);
                        // 设置链表的头元素
                        if (loTail != null) {
                            loTail.next = null;
                            newTab[j] = loHead;
                        }
                        // 设置链表的尾元素
                        if (hiTail != null) {
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }
        return newTab;
    }

    // 替换给定哈希的索引处bin中的所有链接节点
    final void treeifyBin(Node<K, V>[] tab, int hash) {
        // 此处实现省略....
    }

    // 树节点
    static final class TreeNode<K, V> extends LinkedHashMap.Entry<K, V> {
        TreeNode<K, V> parent;   // 红黑树链表
        TreeNode<K, V> left;     // 左节点
        TreeNode<K, V> right;    // 右节点
        TreeNode<K, V> prev;     // 删除后需要取消的链接
        boolean red;            // 红色

        TreeNode(int hash, K key, V val, Node<K, V> next) {
            super(hash, key, val, next);
        }

        final void split(HashMap<K, V> map, Node<K, V>[] tab, int index, int bit) {
            // 此处暂时略........
        }

        final TreeNode<K, V> putTreeVal(HashMap<K, V> map, Node<K, V>[] tab, int h, K k, V v) {
            // 此处暂时略........
            return null;
        }

        final TreeNode<K, V> getTreeNode(int h, Object k) {
            // 此处暂时略........
            return null;
        }

        final void removeTreeNode(HashMap<K, V> map, Node<K, V>[] tab, boolean movable) {
            // 此处暂时略........
        }
    }

    // KeySet类真正实现的是java.util.AbstractSet,此处为了自己实验方便才实现Set接口
    final class KeySet implements Set<K> {
        @Override
        public int size() {
            return 0;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public boolean contains(Object o) {
            return false;
        }

        @Override
        public Iterator<K> iterator() {
            return null;
        }

        @Override
        public Object[] toArray() {
            return new Object[0];
        }

        @Override
        public <T> T[] toArray(T[] a) {
            return null;
        }

        @Override
        public boolean add(K k) {
            return false;
        }

        @Override
        public boolean remove(Object o) {
            return false;
        }

        @Override
        public boolean containsAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean addAll(Collection<? extends K> c) {
            return false;
        }

        @Override
        public boolean retainAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean removeAll(Collection<?> c) {
            return false;
        }

        @Override
        public void clear() {

        } //} extends AbstractSet<K> {

    }

    // Values类真正实现的是java.util.AbstractCollection,此处为了自己实验方便才实现Set接口
    final class Values implements Collection<V> {

        @Override
        public int size() {
            return 0;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public boolean contains(Object o) {
            return false;
        }

        @Override
        public Iterator<V> iterator() {
            return null;
        }

        @Override
        public Object[] toArray() {
            return new Object[0];
        }

        @Override
        public <T> T[] toArray(T[] a) {
            return null;
        }

        @Override
        public boolean add(V v) {
            return false;
        }

        @Override
        public boolean remove(Object o) {
            return false;
        }

        @Override
        public boolean containsAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean addAll(Collection<? extends V> c) {
            return false;
        }

        @Override
        public boolean removeAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean retainAll(Collection<?> c) {
            return false;
        }

        @Override
        public void clear() {

        }
    }

    // EntrySet类真正实现的是java.util.AbstractSet<Map.Entry<K,V>>,此处为了自己实验方便才实现Set接口
    final class EntrySet implements Set<Entry<K, V>> {

        @Override
        public int size() {
            return 0;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public boolean contains(Object o) {
            return false;
        }

        @Override
        public Iterator<Entry<K, V>> iterator() {
            return null;
        }

        @Override
        public Object[] toArray() {
            return new Object[0];
        }

        @Override
        public <T> T[] toArray(T[] a) {
            return null;
        }

        @Override
        public boolean add(Entry<K, V> kvEntry) {
            return false;
        }

        @Override
        public boolean remove(Object o) {
            return false;
        }

        @Override
        public boolean containsAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean addAll(Collection<? extends Entry<K, V>> c) {
            return false;
        }

        @Override
        public boolean retainAll(Collection<?> c) {
            return false;
        }

        @Override
        public boolean removeAll(Collection<?> c) {
            return false;
        }

        @Override
        public void clear() {

        }
    }

    // 返回一个大于cap且距离cap最近的2的幂次方数,比如cap=15,return 16; cap=16,return 16;cap=17,return 32;
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

    /******************************** 其他被调用的方法-end ********************************/

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值