HashMap1.7

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

    /**
     * 默認(rèn)的初始化容積(數(shù)組大型衅簟) - 必需是二的冪写隶。
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;

    /**
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     * 數(shù)組最大的容積三椿,
     * 必需是二的冪秤掌,并且<= 1<<30
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * 負(fù)載因子缓淹,在沒(méi)有主動(dòng)指定的時(shí)候每币,默認(rèn)是0.75f,
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 數(shù)組力麸,根據(jù)需求調(diào)整拐辽,長(zhǎng)度是二的冪磁滚。
     *
     * transient 表示不參與序列化和反序列化
     */
    transient Entry[] table;

    /**
     * 這個(gè)map中的鍵值對(duì)數(shù)量空猜。
     *
     * transient 表示不參與序列化和反序列化
     */
    transient int size;

    /**
     * The next size value at which to resize (capacity * load factor).
     * 擴(kuò)容的參考值,閾值。(容量 * 負(fù)載因子:如果容量是16辈毯,負(fù)載因子是0.75f,閾值就是16 * 0.75f = 12 ,
     * 也就是數(shù)組中Entry數(shù)量達(dá)到12應(yīng)該考慮擴(kuò)容)
     *
     * @serial
     */
    int threshold;

    /**
     * The load factor for the hash table.
     * 負(fù)載因子
     * @serial
     */
    final float loadFactor;

    /**
     * The number of times this HashMap has been structurally modified
     * Structural modifications are those that change the number of mappings in
     * the HashMap or otherwise modify its internal structure (e.g.,
     * rehash).  This field is used to make iterators on Collection-views of
     * the HashMap fail-fast.  (See ConcurrentModificationException).
     *
     * 此HashMap在結(jié)構(gòu)上被修改的次數(shù)
     * 結(jié)構(gòu)修改是指那些更改HashMap中映射的數(shù)量或以其他方式修改其內(nèi)部結(jié)構(gòu)的修改(例如坝疼,rehash)。
     * 此字段用于使HashMap的集合視圖上的迭代器快速失敗(請(qǐng)參閱ConcurrentModificationException)谆沃。
     * hashmap每修改一次钝凶,modCount++;
     *
     * transient 表示不參與序列化和反序列化
     */
    transient int modCount;

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity 初始化容積,數(shù)組大小
     * @param  loadFactor      負(fù)載系數(shù)唁影,滿載率
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            //初始化容量不能小于0
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            //初始化容量最大只能是MAXIMUM_CAPACITY
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            //負(fù)載因子必需>0,并且是一個(gè)合法的數(shù)字
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        // Find a power of 2 >= initialCapacity
        //尋找一個(gè)剛好不小于initialCapacity的數(shù)耕陷,并且滿足它是二的冪這個(gè)要求,作為初始容量据沈。
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;

        //初始化負(fù)載因子哟沫。
        this.loadFactor = loadFactor;
        //初始化擴(kuò)容的閾值
        threshold = (int)(capacity * loadFactor);
        //hashmap的tab數(shù)組的元素,是Entry類(lèi)型的
        //有的版本不是在這里初始化的锌介,而是在put第一個(gè)數(shù)據(jù)的時(shí)候初始化的
        table = new Entry[capacity];
        init();
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param  initialCapacity the initial capacity.
     * @throws IllegalArgumentException if the initial capacity is negative.
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
     * (16) and the default load factor (0.75).
     */
    public HashMap() {
        //默認(rèn)的負(fù)載因子
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        //默認(rèn)長(zhǎng)度16的數(shù)組長(zhǎng)度
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }

    /**
     * Constructs a new <tt>HashMap</tt> with the same mappings as the
     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
     * default load factor (0.75) and an initial capacity sufficient to
     * hold the mappings in the specified <tt>Map</tt>.
     *
     * @param   m the map whose mappings are to be placed in this map
     * @throws  NullPointerException if the specified map is null
     */
    public HashMap(Map<? extends K, ? extends V> m) {
        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
                      DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
        putAllForCreate(m);
    }

    // internal utilities

    
    void init() {
    }

    /**
     * Applies a supplemental hash function to a given hashCode, which
     * defends against poor quality hash functions.  This is critical
     * because HashMap uses power-of-two length hash tables, that
     * otherwise encounter collisions for hashCodes that do not differ
     * in lower bits. Note: Null keys always map to hash 0, thus index 0.
     * 對(duì)最初的hashCode再做一次hash嗜诀,因?yàn)樽畛醯膆ashCode 有的值很大,有的值是負(fù)數(shù)孔祸,質(zhì)量不好隆敢,需要進(jìn)一步處理。
     * 這一點(diǎn)很關(guān)鍵崔慧,因?yàn)镠ashMap使用兩個(gè)長(zhǎng)度哈希表的冪拂蝎,否則會(huì)遇到在低位沒(méi)有差異的哈希碼的沖突。
     * 注意:空鍵總是映射到散列0惶室,因此索引為0温自。
     *
     */
    static int hash(int h) {
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        //二次hash,擾動(dòng)
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

    /**
     * Returns index for hash code h.
     */
    static int indexFor(int h, int length) {
        //如果長(zhǎng)度是16,hash &15,就是取 hash二進(jìn)制 & 1111
        //最后取得數(shù)在0 ~ 15之間皇钞,即數(shù)組的index
        return h & (length-1);
    }

    /**
     * Returns the number of key-value mappings in this map.
     *
     * @return the number of key-value mappings in this map
     */
    public int size() {
        return size;
    }

    /**
     * Returns <tt>true</tt> if this map contains no key-value mappings.
     *
     * @return <tt>true</tt> if this map contains no key-value mappings
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * Returns the value to which the specified key is mapped,
     * or {@code null} if this map contains no mapping for the key.
     *
     * <p>More formally, if this map contains a mapping from a key
     * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
     * key.equals(k))}, then this method returns {@code v}; otherwise
     * it returns {@code null}.  (There can be at most one such mapping.)
     *
     * <p>A return value of {@code null} does not <i>necessarily</i>
     * indicate that the map contains no mapping for the key; it's also
     * possible that the map explicitly maps the key to {@code null}.
     * The {@link #containsKey containsKey} operation may be used to
     * distinguish these two cases.
     *
     * @see #put(Object, Object)
     */
    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }

    /**
     * Offloaded version of get() to look up null keys.  Null keys map
     * to index 0.  This null case is split out into separate methods
     * for the sake of performance in the two most commonly used
     * operations (get and put), but incorporated with conditionals in
     * others.
     */
    private V getForNullKey() {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null)
                return e.value;
        }
        return null;
    }

    /**
     * Returns <tt>true</tt> if this map contains a mapping for the
     * specified key.
     *
     * @param   key   The key whose presence in this map is to be tested
     * @return <tt>true</tt> if this map contains a mapping for the specified
     * key.
     */
    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }

    /**
     * Returns the entry associated with the specified key in the
     * HashMap.  Returns null if the HashMap contains no mapping
     * for the key.
     */
    final Entry<K,V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }


    /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     * 將鍵值放入map,如果之前已經(jīng)放入過(guò)相同的Key悼泌,則新的value覆蓋舊的value
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        if (key == null)
            //key如果是null,將數(shù)據(jù)放入table[0]的位置
            return putForNullKey(value);

        //根據(jù)key的hashCode(),計(jì)算優(yōu)化后的hash,更大程度上防止哈希沖突
        int hash = hash(key.hashCode());
        //根據(jù)hash,數(shù)組長(zhǎng)度計(jì)算出當(dāng)前這個(gè)數(shù)據(jù)的index
        int i = indexFor(hash, table.length);
        //獲取這個(gè)位置的Entry,如果有數(shù)據(jù)鹅士,說(shuō)明相同hash的數(shù)據(jù)之前在存放過(guò)
        //如果這樣就遍歷這個(gè)鏈表券躁,尋找key相同的數(shù)據(jù)惩坑,用新的value替換舊的value,返回舊值
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            //hash相同掉盅,key滿足相同引用或者滿足equals都可以
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                //發(fā)生value替換,返回舊值
                return oldValue;
            }
        }

        //沒(méi)有找到key相同的entry,就需要添加一個(gè)新的Entry

        //為了"并發(fā)修改異常"以舒, modCount自增
        modCount++;
        //添加新的Entry
        addEntry(hash, key, value, i);
        //如果發(fā)生覆蓋趾痘,會(huì)返回舊的value,如果只是添加新的Entry蔓钟,返回null
        return null;
    }

    /**
     * Offloaded version of put for null keys
     */
    private V putForNullKey(V value) {
        //獲取數(shù)組的第一個(gè)元素table[0],
        //然后遍歷這個(gè)table[0]的鏈表
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            //如果發(fā)現(xiàn)一個(gè)key為null的數(shù)據(jù)永票,就將舊值用新值替換,返回舊值
            //這種修改,不會(huì)改變數(shù)據(jù)的結(jié)構(gòu)侣集,不影響遍歷键俱,所以不會(huì)觸發(fā)"并發(fā)修改異常",不用對(duì)modCount自增
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        //之前都沒(méi)有出現(xiàn)過(guò)key為null的數(shù)據(jù)世分,此時(shí)添加進(jìn)來(lái)编振,有可能觸發(fā)并發(fā)修改異常,所以modCount需要自增
        modCount++;
        //將數(shù)據(jù)添加到鏈表臭埋,使用頭插法
        addEntry(0, null, value, 0);
        return null;
    }

    /**
     * This method is used instead of put by constructors and
     * pseudoconstructors (clone, readObject).  It does not resize the table,
     * check for comodification, etc.  It calls createEntry rather than
     * addEntry.
     */
    private void putForCreate(K key, V value) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);

        /**
         * Look for preexisting entry for key.  This will never happen for
         * clone or deserialize.  It will only happen for construction if the
         * input Map is a sorted map whose ordering is inconsistent w/ equals.
         */
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k)))) {
                e.value = value;
                return;
            }
        }

        createEntry(hash, key, value, i);
    }

    private void putAllForCreate(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            putForCreate(e.getKey(), e.getValue());
    }

    /**
     * Rehashes the contents of this map into a new array with a
     * larger capacity.  This method is called automatically when the
     * number of keys in this map reaches its threshold.
     *
     * If current capacity is MAXIMUM_CAPACITY, this method does not
     * resize the map, but sets threshold to Integer.MAX_VALUE.
     * This has the effect of preventing future calls.
     *
     * @param newCapacity the new capacity, MUST be a power of two;
     *        must be greater than current capacity unless current
     *        capacity is MAXIMUM_CAPACITY (in which case value
     *        is irrelevant). 新的數(shù)組容量踪央,必需是2的冪,必需比當(dāng)前的容量大瓢阴,除非當(dāng)前容量是MAXIMUM_CAPACITY
     */
    void resize(int newCapacity) {
        //標(biāo)記舊的數(shù)組
        Entry[] oldTable = table;
        //記錄舊數(shù)組的容量
        int oldCapacity = oldTable.length;
        //如果舊的容量是最大容量畅蹂,給閾值設(shè)為Integer.MAX_VALUE表示無(wú)限大,并且返回荣恐,不進(jìn)行擴(kuò)容液斜。
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }

        //如果容量沒(méi)到最大值,就創(chuàng)建新容量大小的數(shù)組
        Entry[] newTable = new Entry[newCapacity];
        //然后將舊數(shù)組中的數(shù)據(jù)轉(zhuǎn)移到新的數(shù)組中
        transfer(newTable);
        //完成轉(zhuǎn)換
        table = newTable;
        //設(shè)置新的閾值募胃,新的閾值 = 新的數(shù)組容量 * 負(fù)載因子
        threshold = (int)(newCapacity * loadFactor);
    }

    /**
     * Transfers all entries from current table to newTable.
     * 轉(zhuǎn)移所有的Entries到新的數(shù)組newTable
     */
    void transfer(Entry[] newTable) {
        //標(biāo)記原來(lái)的數(shù)組
        Entry[] src = table;
        //新數(shù)組的長(zhǎng)度
        int newCapacity = newTable.length;
        //遍歷原數(shù)組
        for (int j = 0; j < src.length; j++) {
            Entry<K,V> e = src[j];
            if (e != null) {
                src[j] = null;
                //遍歷鏈表
                do {
                    //記錄下一個(gè)節(jié)點(diǎn)
                    Entry<K,V> next = e.next;
                    //計(jì)算當(dāng)前節(jié)點(diǎn)在新數(shù)組的位置index,有50%的機(jī)會(huì)相同
                    int i = indexFor(e.hash, newCapacity);
                    //轉(zhuǎn)換
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }

    /**
     * Copies all of the mappings from the specified map to this map.
     * These mappings will replace any mappings that this map had for
     * any of the keys currently in the specified map.
     *
     * @param m mappings to be stored in this map
     * @throws NullPointerException if the specified map is null
     */
    public void putAll(Map<? extends K, ? extends V> m) {
        int numKeysToBeAdded = m.size();
        if (numKeysToBeAdded == 0)
            return;

        /*
         * Expand the map if the map if the number of mappings to be added
         * is greater than or equal to threshold.  This is conservative; the
         * obvious condition is (m.size() + size) >= threshold, but this
         * condition could result in a map with twice the appropriate capacity,
         * if the keys to be added overlap with the keys already in this map.
         * By using the conservative calculation, we subject ourself
         * to at most one extra resize.
         */
        if (numKeysToBeAdded > threshold) {
            int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
            if (targetCapacity > MAXIMUM_CAPACITY)
                targetCapacity = MAXIMUM_CAPACITY;
            int newCapacity = table.length;
            while (newCapacity < targetCapacity)
                newCapacity <<= 1;
            if (newCapacity > table.length)
                resize(newCapacity);
        }

        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }

    /**
     * Removes the mapping for the specified key from this map if present.
     *
     * @param  key key whose mapping is to be removed from the map
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V remove(Object key) {
        Entry<K,V> e = removeEntryForKey(key);
        return (e == null ? null : e.value);
    }

    /**
     * Removes and returns the entry associated with the specified key
     * in the HashMap.  Returns null if the HashMap contains no mapping
     * for this key.
     */
    final Entry<K,V> removeEntryForKey(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);
        Entry<K,V> prev = table[i];
        Entry<K,V> e = prev;

        while (e != null) {
            Entry<K,V> next = e.next;
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k)))) {
                modCount++;
                size--;
                if (prev == e)
                    table[i] = next;
                else
                    prev.next = next;
                e.recordRemoval(this);
                return e;
            }
            prev = e;
            e = next;
        }

        return e;
    }

    /**
     * Removes all of the mappings from this map.
     * The map will be empty after this call returns.
     */
    public void clear() {
        modCount++;
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            tab[i] = null;
        size = 0;
    }

    /**
     * Returns <tt>true</tt> if this map maps one or more keys to the
     * specified value.
     *
     * @param value value whose presence in this map is to be tested
     * @return <tt>true</tt> if this map maps one or more keys to the
     *         specified value
     */
    public boolean containsValue(Object value) {
        if (value == null)
            return containsNullValue();

        Entry[] tab = table;
        for (int i = 0; i < tab.length ; i++)
            for (Entry e = tab[i] ; e != null ; e = e.next)
                if (value.equals(e.value))
                    return true;
        return false;
    }

    /**
     * Special-case code for containsValue with null argument
     */
    private boolean containsNullValue() {
        Entry[] tab = table;
        for (int i = 0; i < tab.length ; i++)
            for (Entry e = tab[i] ; e != null ; e = e.next)
                if (e.value == null)
                    return true;
        return false;
    }

    /**
     * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and
     * values themselves are not cloned.
     *
     * @return a shallow copy of this map
     */
    public Object clone() {
        HashMap<K,V> result = null;
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // assert false;
        }
        result.table = new Entry[table.length];
        result.entrySet = null;
        result.modCount = 0;
        result.size = 0;
        result.init();
        result.putAllForCreate(this);

        return result;
    }

    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;

        /**
         * Creates new entry.
         */
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }

        public final K getKey() {
            return key;
        }

        public final V getValue() {
            return value;
        }

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

        public final boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry)o;
            Object k1 = getKey();
            Object k2 = e.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                Object v1 = getValue();
                Object v2 = e.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2)))
                    return true;
            }
            return false;
        }

        public final int hashCode() {
            return (key==null   ? 0 : key.hashCode()) ^
                   (value==null ? 0 : value.hashCode());
        }

        public final String toString() {
            return getKey() + "=" + getValue();
        }
        
    }

    /**
     * Adds a new entry with the specified key, value and hash code to
     * the specified bucket.  It is the responsibility of this
     * method to resize the table if appropriate.
     * 將含有特定的key,value旗唁,hash的一個(gè)新的entry,放入指定的桶中(table[index]就是一個(gè)桶),
     * 如果合適痹束,是可以擴(kuò)容的检疫。
     *
     * Subclass overrides this to alter the behavior of put method.
     * //子類(lèi)可以覆寫(xiě)這個(gè)方法,修改存放的操作祷嘶。
     */
    void addEntry(int hash, K key, V value, int bucketIndex) {
        //獲取要存放到哪個(gè)桶中屎媳,這個(gè)桶是一個(gè)鏈表,
        // 這個(gè)鏈表的頭節(jié)點(diǎn)需要被新添加的Entry的next引用论巍,
        //由此可見(jiàn)烛谊,這里的添加操作采用的是"頭插法",
        // Oracle的工程師可能覺(jué)得后添加的數(shù)據(jù)使用頻率更高嘉汰,基于查詢(xún)速度的考慮丹禀,采用這種方式
        Entry<K,V> e = table[bucketIndex];
        //創(chuàng)建一個(gè)Entry(hash, key, value, next指向的Entry節(jié)點(diǎn))
        //將新創(chuàng)建的節(jié)點(diǎn)存入table[桶位置]
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        //添加完數(shù)據(jù)之后,size++
        //然后需要判斷此時(shí)是否需要擴(kuò)容
        if (size++ >= threshold)
            //擴(kuò)容后鞋怀,新的數(shù)組長(zhǎng)度擴(kuò)大2倍双泪,因?yàn)閿?shù)組的長(zhǎng)度需要保持為2的冪。
            resize(2 * table.length);
    }

    /**
     * Like addEntry except that this version is used when creating entries
     * as part of Map construction or "pseudo-construction" (cloning,
     * deserialization).  This version needn't worry about resizing the table.
     *
     * Subclass overrides this to alter the behavior of HashMap(Map),
     * clone, and readObject.
     * 創(chuàng)建Entry密似,保存到bucketIndex
     */
    void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        //頭插法焙矛,新的Entry放在鏈表頭
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        //數(shù)據(jù)數(shù)量自增
        size++;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市残腌,隨后出現(xiàn)的幾起案子村斟,更是在濱河造成了極大的恐慌贫导,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蟆盹,死亡現(xiàn)場(chǎng)離奇詭異孩灯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)逾滥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)钱反,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人匣距,你說(shuō)我怎么就攤上這事面哥。” “怎么了毅待?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵尚卫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我尸红,道長(zhǎng)吱涉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任外里,我火速辦了婚禮怎爵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盅蝗。我一直安慰自己鳖链,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布墩莫。 她就那樣靜靜地躺著芙委,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狂秦。 梳的紋絲不亂的頭發(fā)上灌侣,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音裂问,去河邊找鬼侧啼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛堪簿,可吹牛的內(nèi)容都是我干的痊乾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼戴甩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼符喝!你這毒婦竟也來(lái)了闪彼?” 一聲冷哼從身側(cè)響起甜孤,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤协饲,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后缴川,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體茉稠,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年把夸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了而线。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恋日,死狀恐怖膀篮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岂膳,我是刑警寧澤誓竿,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站谈截,受9級(jí)特大地震影響筷屡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜簸喂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一毙死、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喻鳄,春花似錦扼倘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至竿奏,卻和暖如春袄简,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泛啸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工绿语, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人候址。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓吕粹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親岗仑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匹耕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容