HashMap

1.HashMap是一个数组+链表/红黑树的结构,数组的下标在HashMap中称为Bucket值,每个数组项对应的是一个List

2.每个List中存放的是一个Entry对象,这个Entry对象是包含键和值的

HashMap类实现了诸多接口Map, Cloneable, Serializable

public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {

常量

private static final long serialVersionUID =362498820763181265L;

    //最小容量

    static final int DEFAULT_INITIAL_CAPACITY =1 <<4; // aka 16

    //最大容量

    static final int MAXIMUM_CAPACITY =1 <<30;

    //重载因子

    static final float DEFAULT_LOAD_FACTOR =0.75f;

    //链表的最大长度,超过之后变为红黑树

    static final int TREEIFY_THRESHOLD =8;

  //红黑树当总的元素量小于6时,变成链表

    static final int UNTREEIFY_THRESHOLD =6;

   //当桶中的bin元素被树化时,桶的最小容量必须大于4 * TREEIFY_THRESHOLD(树化的长度),否则进行resize扩容,

    static final int MIN_TREEIFY_CAPACITY =64;

内部静态类Node

 Basic hash bin node, used for most entries.

    static class Node implements Map.Entry<K,V> {

        final int hash;

        final K key;

        V 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;

        }

    public final K getKey()        {return key; }

    public final V getValue()      {return value; }

    public final String toString() {return key +"=" +value; }

    public final int hashCode() {

        return Objects.hashCode(key) ^ Objects.hashCode(value);

        }

    public final V setValue(V newValue) {

        V oldValue =value;

            value = newValue;

            return oldValue;

        }

    public final boolean equals(Object o) {

            if (o == this)

                    return true;

            if (o instanceof Map.Entry) {

                Map.Entry<?,?> e = (Map.Entry<?,?>)o;

                if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue()))

                        return true;

            }

            return false;

        }

}

静态工具

/* ---------------- Static utilities -------------- */

    //哈希化

    static final int hash(Object key) {

        int h;

    //^优先级高于三目运算符,>>>无符号右移16位

    //如果该类有hashCode的实现会优先调用自身的hashCode方法,没有的话将调用Object的hashCode方法;

        return (key ==null) ? 0 : (h = key.hashCode()) ^ (h >>>16);

    }

比较方法

    static Class<?> comparableClassFor(Object x) {

        if (x instanceof Comparable) {

            Class c; Type[] ts, as; Type t; ParameterizedType p;

            if ((c = x.getClass()) == String.class) // bypass checks

                return c;

            if ((ts = c.getGenericInterfaces()) !=null) {

                        for (int i = 0; i < ts.length; ++i) {

                                if (((t = ts[i])instanceof ParameterizedType) &&

                                    ((p = (ParameterizedType)t).getRawType() == Comparable.class)                                 && (as = p.getActualTypeArguments()) !=null

                                && as.length ==1

                                && as[0] == c) // type arg is c

                        return c;

                }

            }

        }

        return null;

    }

可比较的

    @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable

    //原文是/rawtypes , unchecked/

    static int compareComparables(Class kc, Object k, Object x) {

//逻辑运算符高于三目运算符

            return (x ==null || x.getClass() != kc ?0 :

                    ((Comparable)k).compareTo(x));

    }

为给定目标容量,返回一个容器的尺寸

    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;

    }

/* ---------------- Fields -------------- */

属性

    transient Node[] table; //元素集合

    transient Set<Map.Entry<K,V>> entrySet; //缓存的Map.Entry集合

    transient int size; //大小

    transient int modCount; // HashMap被改变的次数 

     //HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子) 

   int threshold;

   final float loadFactor; // 加载因子实际大小 

    /* ---------------- Public operations -------------- */

构造器

    //带初始化大小和负载因子的构造器

    public HashMap(int initialCapacity, float loadFactor) {

            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);//大小为2的次幂

    }

  //不带负载因子的构造器,默认为0.75

    public HashMap(int initialCapacity) {

        this(initialCapacity, DEFAULT_LOAD_FACTOR);

    }

//构造一个空的HashMap对象,默认打下为16,负载因子0.75

    public HashMap() {

            this.loadFactor =DEFAULT_LOAD_FACTOR; // all other fields defaulted

    }

//通过Map构造一个HashMap, 负载因子默认为0.75,通过 putMapEntries方法,将Map中的值放入HashMap当中

public HashMap(Map<? extends K, ? extends V>  m) {

        this.loadFactor =DEFAULT_LOAD_FACTOR;

        putMapEntries(m, false);

    }

//Implements Map.putAll and Map constructor

    final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {

         int s = m.size();

        if (s >0) {//判断map的大小

                if (table ==null) {// pre-size,判断hashMap的初始大小

                   float ft = ((float)s /loadFactor) +1.0F; //判断这个创建数组的大小

                    int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft  :                             MAXIMUM_CAPACITY);

                    if (t >threshold)//设置容器大小 , threshold初始为0

                            threshold = tableSizeFor(t);

                } else if (s  > threshold) //若大于现有长度将扩容

                   resize();//扩容

            for (Map.Entry e : m.entrySet()) {

                K key = e.getKey();

                V value = e.getValue();

                putVal(hash(key), key, value, false, evict);

            }

    }

}

获取当前的存储key-value的数量

    public int size() {

            return size;

    }

判断是否为空

    public boolean isEmpty() {

            return size ==0;

    }

按照key获取value

    public V get(Object key) {

        Node<K,V> e;

        return (e = getNode(hash(key), key)) ==null ?null : e.value;

    }

通过key和hashCode获取Node

    final Node<K,V> getNode(int hash, Object key) {

        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;

        //hash是key哈希化的int值,与数组的最大下标进行安位与运算,得出实际的位置

        if ((tab =table) !=null && (n = tab.length) >0 &&  (first = tab[(n -1) & hash]) !=null) {

            if (first.hash == hash &&// always check first node

                    ((k = first.key) == key || (key !=null && key.equals(k))))

                    return first;

            //若第一个并不是所要找的元素,则进行分类查找(树/链表)

            if ((e = first.next) !=null) {

                //树(红黑树)

                if (first instanceof TreeNode)

                            return ((TreeNode<K,V>)first).getTreeNode(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;

    }

判断是否包含某个key

    public boolean containsKey(Object key) {

        return getNode(hash(key), key) !=null;

    }

放入Map

    public V put(K key, V value) {

            //参数:hashCode,key, value, onlyIfAbsent(如果原来的key不存在创建,存在则不做任何操作, false默认(即替代原有value),true), evict()

            return putVal(hash(key), key, value, false, true);

    }

插入HashMap

参数:hashCode,key, value, onlyIfAbsent(如果原来的key不存在创建,存在则不做任何操作, false默认(即替代原有value),true), evict(用于LinkedHashMap中的尾部操作,这里没有实际意义。)

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {

        Node<K,V>[] tab; Node<K,V> p; int n, i;

        //判断长度是否为0,若为0,则初始化

        if ((tab =table) ==null || (n = tab.length) ==0)

                    n = (tab = resize()).length;

        //获取Node[] 数组的该位置是否有值,无值直接放入

        if ((p = tab[i = (n -1) & hash]) ==null)

                   tab[i] = newNode(hash, key, value, null);

       //有值的话,则添加到链表或者树上

        else {

            Node<K,V> e; K k;

            //传入的hashCode和key都与现有的节点相同

            if (p.hash == hash &&((k = p.key) == key || (key !=null && key.equals(k))))

                    e = p;

           //传入的hashCode和key都与现有的节点不相同,则分为两种情况,树/链表

           //树

            else if (p instanceof TreeNode)

                    //插入一个树节点

                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);

            //链表

            else {

                for (int binCount =0; ; ++binCount) {

                    //下一个节点为空则创建

                    if ((e = p.next) ==null) {

                        //插入一个链表节点

                        p.next = newNode(hash, key, value, null);

                        //判断添加后链表的长度,超过8则转换为红黑树

                        if (binCount >=TREEIFY_THRESHOLD -1)// -1 for 1st

                            //转换为红黑树

                            treeifyBin(tab, hash);

                            break;

                    }

                   //哈希化找到该节点,则返回e

                    if (e.hash == hash &&

                            ((k = e.key) == key || (key !=null && key.equals(k))))

                            break;

                //将当前节点在付给p,继续循环

                    p = e;

                }

        }

        if (e !=null) {// existing mapping for key

                V oldValue = e.value;

                //判断onlyIfAbsent,改写方式

                if (!onlyIfAbsent || oldValue ==null)

                        e.value = value;

                afterNodeAccess(e);//插入节点后,允许的回调方法,可重写

                return oldValue;

            }

        }

        ++modCount;//结构被更改的次数

        //当插入节点后,根据负载因子判断是否扩容

        if (++size >threshold)

                resize();

        afterNodeInsertion(evict);//结构调整后,允许的回调函数

        return null;

    }

重新定义hashMap的大小,初始化或者2次幂的方式扩容

    final 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) {

                //达到最大值

                if (oldCap >=MAXIMUM_CAPACITY) {

                        threshold = Integer.MAX_VALUE;

                        return oldTab;

                }

                //按照2次幂方式扩容

                else if ((newCap = oldCap <<1) < MAXIMUM_CAPACITY

                        && oldCap >=DEFAULT_INITIAL_CAPACITY)

                        newThr = oldThr <<1; // double threshold

        }

            //如果有容量限制则为原值

            else if (oldThr >0)// initial capacity was placed in threshold

                    newCap = oldThr;

            //没有固定参数,设置为默认值

             else {// zero initial threshold signifies using defaults

                        newCap =DEFAULT_INITIAL_CAPACITY;//16

                        newThr = (int)(DEFAULT_LOAD_FACTOR                                                 * DEFAULT_INITIAL_CAPACITY);

        }

        //确定新的存储量是多少

        if (newThr ==0) {

                  float ft = (float)newCap *loadFactor;

                  newThr = (newCap < MAXIMUM_CAPACITY && ft <                                 (float)MAXIMUM_CAPACITY? (int)ft : Integer.MAX_VALUE);

        }

        //新的阀值

        threshold = newThr;

        @SuppressWarnings({"rawtypes","unchecked"})

        //创建一个新的数组

        Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];

        table = newTab;

        if (oldTab !=null) {

            for (int j =0; j < oldCap; ++j) {

                Node e;

                if ((e = oldTab[j]) !=null) {

                    oldTab[j] =null;

                    //如果没有链表和树直接付值

                    if (e.next ==null)

                        newTab[e.hash & (newCap -1)] = e;

                    //如果是红黑树

                    else if (e instanceof TreeNode)

                        //将树拆分成高低两个树,重新进行哈希化,然后put

                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);

                    //如果是链表的话

                    else {// preserve order

                        Node<K,V> loHead =null, loTail =null;

                        Node<K,V> hiHead =null, hiTail =null;

                        Node<K,V> next;

                        do {

                                next = e.next;

                            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;

    }

链表长度超过8,将调整链表为树

    final void treeifyBin(Node<K,V>[] tab, int hash) {

        int n, index; Node e;

        //当有树存在时,最小容量必须大于4*树化阀值(8)。默认64

        if (tab ==null || (n = tab.length) < MIN_TREEIFY_CAPACITY) resize();

        else if ((e = tab[index = (n -1) & hash]) !=null) {

            TreeNode<K,V> hd =null, tl =null;

        //循环替换

            do {

                //将node节点化成TreeNode节点

                TreeNode<K,V> p = replacementTreeNode(e, null);

                //设置根节点

                if (tl ==null)

                    hd = p;

                //设置父节点

                else {

                    p.prev = tl;

                    tl.next = p;

                }

                tl = p;

            }while ((e = e.next) !=null);

            //将头节点放到整个数组当中

            if ((tab[index] = hd) !=null)

                //从头节点开始树化

                hd.treeify(tab);

        }

}

将Map插入全部

    public void putAll(Map m) {

            putMapEntries(m, true);

    }

删除节点

    public V remove(Object key) {

                Node e;

                return (e = removeNode(hash(key), key, null, false, true)) ==null

                        ? null : e.value;

    }

删除节点

参数int hash(哈希值), Object key, Object value(一般为nu l l),  boolean matchValue(是否value也一致时在删除,默认为false), boolean movable(是否移动其他节点,在树的时候, 默认为true)

    final Node<K,V> removeNode(int hash, Object key, Object value,

                              boolean matchValue, boolean movable) {

         Node<K,V>[] tab; Node<K,V> p; int n, index;

        //查找到要删除的桶

        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)p).getTreeNode(hash, key);

                    //链表

                     else {

                            do {

                                    if (e.hash == hash && ((k = e.key) == key ||

                                                    (key !=null && key.equals(k)))) {

                                                node = e;

                                                break;

                                    }

                                    p = e;

                                }while ((e = e.next) !=null);

                    }

        }

        //获取到相应的node节点

        if (node !=null && (!matchValue || (v = node.value) == value ||

                                                   (value !=null && value.equals(v)))) {

                //树

                if (node instanceof TreeNode)

                        ((TreeNode)node).removeTreeNode(this, tab, movable);

            //链表

            //头节点

                else if (node == p)

                        tab[index] = node.next;

            //非头节点

                else

                    p.next = node.next;

                ++modCount;

                --size;

                afterNodeRemoval(node);

                return node;

            }

        }

        return null;

    }

清除方法

    public void clear() {

         Node<K,V>[] tab;

        modCount++;

        if ((tab =table) !=null &&size >0) {

                size =0;

                for (int i =0; i < tab.length; ++i)

                    tab[i] =null;

        }

}

是否包含值

    public boolean containsValue(Object value) {

            Node[] tab; V v;

            if ((tab =table) !=null &&size >0) {

                    for (int i =0; i < tab.length; ++i) {

                        for (Node e = tab[i]; e !=null; e = e.next) {

                            if ((v = e.value) == value ||(value !=null && value.equals(v)))

                                return true;

                            }

                    }

            }

        return false;

    }

key的集合

    public SetkeySet() {

            Set ks =keySet;

            if (ks ==null) {

                 ks =new KeySet();

                keySet = ks;

            }

        return ks;

    }

内部类KeySet

final class KeySet extends AbstractSet<K> {

        public final int size()                {return size; }

        public final void clear()              { HashMap.this.clear(); }

        public final Iterator<K> iterator()    {return new KeyIterator(); }

        public final boolean contains(Object o) {return containsKey(o); }

        public final boolean remove(Object key) {

                return removeNode(hash(key), key, null, false, true) !=null;

        }

        //Spliterator就是为了并行遍历元素而设计的一个迭代器,对于迭代器中数据进行分割

        public final Spliterator<K> spliterator() {

                return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);

        }

    //遍历

    public final void forEach(Consumer action) {

            Node[] tab;

            if (action ==null)

                throw new NullPointerException();

            if (size >0 && (tab =table) !=null) {

                int mc =modCount;

                for (int i =0; i < tab.length; ++i) {

                        for (Node e = tab[i]; e !=null; e = e.next)

                                action.accept(e.key);

                }

                if (modCount != mc)

                        throw new ConcurrentModificationException();

            }

        }

}

获取全部的值

    public Collection<V> values() {

        Collection vs =values;

        if (vs ==null) {

            vs =new Values();

            values = vs;

        }

        return vs;

    }

Value的集合类

final class Values extends AbstractCollection<V> {

    public final int size()                {return size; }

    public final void clear()              { HashMap.this.clear(); }

    public final Iterator<V> iterator()    {return new ValueIterator(); }

    public final boolean contains(Object o) {return containsValue(o); }

    public final Spliterator<V> spliterator() {

            return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);

        }

        public final void forEach(Consumer<? super V> action) {

            Node<K,V>[] tab;

            if (action ==null)

                throw new NullPointerException();

            if (size >0 && (tab =table) !=null) {

                int mc =modCount;

                for (int i =0; i < tab.length; ++i) {

                    for (Node e = tab[i]; e !=null; e = e.next)

                        action.accept(e.value);

                }

                if (modCount != mc)

                    throw new ConcurrentModificationException();

            }

    }

}

set集合

    public Set<Map.Entry<K,V>> entrySet() {

        Set<Map.Entry<K,V>> es;

        return (es =entrySet) ==null ? (entrySet =new EntrySet()) : es;

    }

内部类EntrySet

final class EntrySet extends AbstractSet<Map.Entry<K,V>> {

    public final int size()                {return size; }

    public final void clear()              { HashMap.this.clear(); }

    public final Iterator<Map.Entry<K,V>>iterator() {

            return new EntryIterator();

    }

    public final boolean contains(Object o) {

            if (!(oinstanceof Map.Entry))

                    return false;

            Map.Entry<?,?> e = (Map.Entry<?,?>) o;

            Object key = e.getKey();

            Node<K,V> candidate = getNode(hash(key), key);

            return candidate !=null && candidate.equals(e);

        }

    public final boolean remove(Object o) {

        if (o instanceof Map.Entry) {

                Map.Entry<?,?> e = (Map.Entry<?,?>) o;

                Object key = e.getKey();

                Object value = e.getValue();

                return removeNode(hash(key), key, value, true, true) !=null;

            }

            return false;

        }

        public final Spliterator<Map.Entry<K,V>>spliterator() {

            return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);

        }

public final void forEach(Consumer> action) {

            Node<K,V>[] tab;

            if (action ==null)

                    throw new NullPointerException();

            if (size >0 && (tab =table) !=null) {

                int mc =modCount;

                for (int i =0; i < tab.length; ++i) {

                    for (Node e = tab[i]; e !=null; e = e.next)

                        action.accept(e);

                }

                if (modCount != mc)

                throw new ConcurrentModificationException();

            }

       }

}

获取默认值

    public V getOrDefault(Object key, V defaultValue) {

         Node e;

        return (e = getNode(hash(key), key)) ==null ? defaultValue : e.value;

    }

key存在则不插入

    public V putIfAbsent(K key, V value) {

        return putVal(hash(key), key, value, true, true);

    }

删除节点

    public boolean remove(Object key, Object value) {

            return removeNode(hash(key), key, value, true, true) !=null;

    }

替换旧值

    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;

                fterNodeAccess(e);

                return true;

        }

           return false;

    }

替换旧值

    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;

    }

compute()是java8在Map中新增的一个方法,其作用是把remappingFunction的计算结果关联到key上(即remappingFunction返回值作为新value)


 V computeIfAbsent根据key做匹配Node,(匹配不到则新建然后重排)如果Node有value,则直接返回oldValue,如果没有value则根据Function接口的apply方法获取value,返回value。Function接口的apply的入参为key,调用computeIfAbsent时重写Function接口可以根据key进行逻辑处理,apply的返回值即为要存储的value。

    public V computeIfAbsent(K key,

                           Function mappingFunction<? super K, ? extends V> mappingFunction) {

          if (mappingFunction ==null)

                                    throw new NullPointerException();

            int hash =hash(key);

            Node<K,V>[] tab; Node<K,V> first; int n, i;

            int binCount =0;

            TreeNode<K,V> t =null;

            Node<K,V> old =null;

            if (size >threshold || (tab =table) ==null || (n = tab.length) ==0)

                n = (tab = resize()).length;

            if ((first = tab[i = (n -1) & hash]) !=null) {

                if (firstinstanceof TreeNode)

                    old = (t = (TreeNode)first).getTreeNode(hash, key);

                else {

                        Node e = first; K k;

                        do {

                            if (e.hash == hash &&((k = e.key) == key || (key !=null &&                                     key.equals(k)))) {

                                    old = e;

                                    break;

                                }

                                ++binCount;

                            }while ((e = e.next) !=null);

                    }

                    V oldValue;

                    if (old !=null && (oldValue = old.value) !=null) {

                        afterNodeAccess(old);

                        return oldValue;

                    }

                }

                V v = mappingFunction.apply(key);

                if (v ==null) {

                        return null;

                    }else if (old !=null) {

                        old.value = v;

                        afterNodeAccess(old);

                        return v;

                    }

                    else if (t !=null)

                        t.putTreeVal(this, tab, hash, key, v);

                    else {

                        tab[i] = newNode(hash, key, v, first);

                        if (binCount >=TREEIFY_THRESHOLD -1)

                                treeifyBin(tab, hash);

             }

          ++modCount;

        ++size;

        afterNodeInsertion(true);

        return v;

    }

V computeIfPresent(K key,BiFunction remappingFunction):根据key做匹配,如果匹配不上则返回null,匹配上根据BiFunction的apply方法获取value,返回value。BiFunction接口的apply的入参为key、oldValue,调用computeIfPresent时重写Function接口可以根据key和oldValue进行逻辑处理,apply的返回值如果为null则删除该节点,否则即为要存储的value。

public V computeIfPresent(K key,

                    BiFunction<? super K, ? super V, ? super V> remappingFunction) {

            if (remappingFunction ==null)

                        throw new NullPointerException();

            Node<K,V> e; V oldValue;

            int hash =hash(key);

           if ((e = getNode(hash, key)) !=null &&(oldValue = e.value) !=null) {

                V v = remappingFunction.apply(key, oldValue);

                if (v !=null) {

                    e.value = v;

                    afterNodeAccess(e);

                    return v;

            }

            else

                removeNode(hash, key, null, false, true);

            }

        return null;

    }

V compute(K key,BiFunction remappingFunction):根据key做匹配,根据BiFunction的apply返回做存储的value。匹配到Node做value替换,匹配不到新增node。apply的返回值如果为null则删除该节点,否则即为要存储的value。

    public V compute(K key,

                    BiFunction<? super K, ? super V, ? extends V> remappingFunction) {

            if (remappingFunction ==null)

                        throw new NullPointerException();

              int hash =hash(key);

              Node<K,V>[] tab; Node<K,V> first; int n, i;

               int binCount =0;

                TreeNode<K,V> t =null;

                Node<K,V> old =null;

                if (size >threshold || (tab =table) ==null || (n = tab.length) ==0)

                            n = (tab = resize()).length;

               if ((first = tab[i = (n -1) & hash]) !=null) {

                    if (first instanceof TreeNode)

                        old = (t = (TreeNode)first).getTreeNode(hash, key);

                    else {

                            Node e = first; K k;

                            do {

                                    if (e.hash == hash &&

                                                ((k = e.key) == key || (key !=null && key.equals(k)))) {

                                                old = e;

                                                break;

                                            }

                                        ++binCount;

                                    }while ((e = e.next) !=null);

                            }

                    }

          V oldValue = (old ==null) ?null : old.value;

        V v = remappingFunction.apply(key, oldValue);

        if (old !=null) {

                if (v !=null) {

                    old.value = v;

                    afterNodeAccess(old);

                }

                else  removeNode(hash, key, null, false, true);

            }

            else if (v !=null) {

                if (t !=null)

                        t.putTreeVal(this, tab, hash, key, v);

                    else {

                            tab[i] = newNode(hash, key, v, first);

                            if (binCount >=TREEIFY_THRESHOLD -1)

                                    treeifyBin(tab, hash);

                   }

              ++modCount;

            ++size;

            afterNodeInsertion(true);

        }

        return v;

    }

 V merge(K key, V value,BiFunction remappingFunction):功能大部分与compute相同,不同之处在于BiFunction中apply的参数,入参为oldValue、value,调用merge时根据两个value进行逻辑处理并返回value。

    public V merge(K key, V value,

                  BiFunction remappingFunction) {

            if (value ==null)

                    throw new NullPointerException();

            if (remappingFunction ==null)

                        throw new NullPointerException();

            int hash =hash(key);

            Node<K,V>[] tab; Node first; int n, i;

            int binCount =0;

            TreeNode<K,V> t =null;

            Node<K,V> old =null;

            if (size >threshold || (tab =table) ==null || (n = tab.length) ==0)

                    n = (tab = resize()).length;

            if ((first = tab[i = (n -1) & hash]) !=null) {

                if (first instanceof TreeNode)

                        old = (t = (TreeNode)first).getTreeNode(hash, key);

                else {

                        Node<K,V> e = first; K k;

                        do {

                            if (e.hash == hash &&((k = e.key) == key || (key !=null

                                && key.equals(k)))) {

                                old = e;

                                break;

                        }

                        ++binCount;

                    }while ((e = e.next) !=null);

                }

        }

        if (old !=null) {

            V v;

            if (old.value !=null)

                        v = remappingFunction.apply(old.value, value);

            else

                        v = value;

                        if (v !=null) {

                            old.value = v;

                            afterNodeAccess(old);

                        }

                        else removeNode(hash, key, null, false, true);

                        return v;

            }

            if (value !=null) {

                    if (t !=null)

                            t.putTreeVal(this, tab, hash, key, value);

                    else {

                            tab[i] = newNode(hash, key, value, first);

                            if (binCount >=TREEIFY_THRESHOLD -1)

                                    treeifyBin(tab, hash);

                            }

                    ++modCount;

                    ++size;

                    afterNodeInsertion(true);

                }

        return value;

    }

遍历

    public void forEach(BiConsumer<? super K, ? super V> action) {

            Node[] tab;

            if (action ==null)

                        throw new NullPointerException();

                if (size >0 && (tab =table) !=null) {

                        int mc =modCount;

                       for (int i =0; i < tab.length; ++i) {

                                for (Node<K,V> e = tab[i]; e !=null; e = e.next)

                                            action.accept(e.key, e.value);

                        }

                        if (modCount != mc)

                                    throw new ConcurrentModificationException();

                }

        }

替换所有

    public void replaceAll(BiFunction<? super K, ? super V> function) {

            Node<K,V>[] tab;

             if (function ==null)

                        throw new NullPointerException();

            if (size >0 && (tab =table) !=null) {

                        int mc =modCount;

                        for (int i =0; i < tab.length; ++i) {

                            for (Node<K,V> e = tab[i]; e !=null; e = e.next) {

                                        e.value = function.apply(e.key, e.value);

                                }

                        }

                if (modCount != mc)

                            throw new ConcurrentModificationException();

                }

}

Returns a shallow copy (浅副本,key和Value不被克隆)

    @SuppressWarnings("unchecked")

  public Object clone() {

            HashMap result;

             try {

                        result = (HashMap)super.clone();

                }catch (CloneNotSupportedException e) {

                        throw new InternalError(e);

                }

                result.reinitialize();

                result.putMapEntries(this, false);

                return result;

    }


    final float loadFactor() {return loadFactor; }

final int capacity() {

            return (table !=null) ?table.length :

                        (threshold >0) ?threshold : DEFAULT_INITIAL_CAPACITY;

    }

Save the state of the HashMap instance to a stream (i.e.,

    private void writeObject(java.io.ObjectOutputStream s)throws IOException {

        int buckets = capacity();

        // Write out the threshold, loadfactor, and any hidden stuff

        s.defaultWriteObject();

        s.writeInt(buckets);//容量

        s.writeInt(size);//长度

        internalWriteEntries(s);

    }


    private void readObject(java.io.ObjectInputStream s)throws IOException,                                 ClassNotFoundException {

// Read in the threshold (ignored), loadfactor, and any hidden stuff

        s.defaultReadObject();

        reinitialize();

        if (loadFactor <=0 || Float.isNaN(loadFactor))

                    throw new InvalidObjectException("Illegal load factor: " +loadFactor);

        s.readInt();                // Read and ignore number of buckets

        int mappings = s.readInt(); // Read number of mappings (size)

        if (mappings <0)

            throw new InvalidObjectException("Illegal mappings count: " +mappings);

        else if (mappings >0) {// (if zero, use defaults)

                    // Size the table using given load factor only if within

                    // range of 0.25...4.0

            float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);

            float fc = (float)mappings / lf +1.0f;

            int cap = ((fc<DEFAULT_INITIAL_CAPACITY) ?DEFAULT_INITIAL_CAPACITY :

                (fc >=MAXIMUM_CAPACITY) ?MAXIMUM_CAPACITY :tableSizeFor((int)fc));

            float ft = (float)cap * lf;

            threshold = ((cap< MAXIMUM_CAPACITY && ft<MAXIMUM_CAPACITY) ?

                        (int)ft : Integer.MAX_VALUE);

            @SuppressWarnings({"rawtypes","unchecked"})

            Node<K,V>[] tab = (Node<K,V>[])new Node[cap];

            table = tab;

            // Read the keys and values, and put the mappings in the HashMap

            for (int i =0; i < mappings; i++) {

                    @SuppressWarnings("unchecked")

                    K key = (K) s.readObject();

                    @SuppressWarnings("unchecked")

                    V value = (V) s.readObject();

                    putVal(hash(key), key, value, false, false);

            }

        }

}

HashIterator

    abstract class HashIterator {

        Node<K,V> next;        // next entry to return

        Node<K,V> current;    // current entry

        int expectedModCount;  // for fast-fail

        int index;            // current slot

        HashIterator() {

            expectedModCount =modCount;

            Node<k,V>[] t =table;

            current =next =null;

            index =0;

            if (t !=null &&size >0) {// advance to first entry

                do {}while (index < t.length && (next = t[index++]) ==null);

            }

}

public final boolean hasNext() {

                        return next !=null;

        }

final Node<K,V> nextNode() {

            Node<K,V>[] t;

            Node<K,V> e =next;

            if (modCount !=expectedModCount)

                        throw new ConcurrentModificationException();

            if (e ==null)

                        throw new NoSuchElementException();

            if ((next = (current = e).next) ==null && (t =table) !=null) {

                        do {}while (index < t.length && (next = t[index++]) ==null);

            }

            return e;

        }

public final void remove() {

            Node<K,V> p =current;

            if (p ==null)

                    throw new IllegalStateException();

            if (modCount !=expectedModCount)

                    throw new ConcurrentModificationException();

            current =null;

            K key = p.key;

            removeNode(hash(key), key, null, false, false);

            expectedModCount =modCount;

        }

}

final class KeyIterator extends HashIterator

    implements Iterator<K> {

public final K next() {return nextNode().key; }

}

final class ValueIterator extends HashIterator

    implements Iterator<V> {

    public final V next() {return nextNode().value; }

}

final class EntryIterator extends HashIterator

implements Iterator<Map.Entry<K,V>> {

        public final Map.Entry<K,V> next() {return nextNode(); }

}

可并行迭代器

    static class HashMapSpliterator {

        final HashMap<K,V> map;

        Node<K,V> current;          // current node

        int index;                  // current index, modified on advance/split

        int fence;                  // one past last index

        int est;                    // size estimate

        int expectedModCount;      // for comodification checks

        HashMapSpliterator(HashMap<K,V> m, int origin,

                          int fence, int est,

                          int expectedModCount) {

            this.map = m;

            this.index = origin;

            this.fence = fence;

            this.est = est;

            this.expectedModCount = expectedModCount;

        }

    final int getFence() {// initialize fence and size on first use

            int hi;

            if ((hi =fence) <0) {

                HashMap<K,V> m =map;

                est = m.size;

                expectedModCount = m.modCount;

                Node<K,V>[] tab = m.table;

                hi =fence = (tab ==null) ?0 : tab.length;

            }

        return hi;

        }

public final long estimateSize() {

            getFence(); // force init

            return (long)est;

        }

}

static final class KeySpliterator<K,V> extends HashMapSpliterator<K,V> implements Spliterator<K> {

        KeySpliterator(HashMap<K,V> m, int origin, int fence, int est, int expectedModCount) {

            super(m, origin, fence, est, expectedModCount);

        }

public KeySpliterator<K,V> trySplit() {

            int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

            return (lo >= mid ||current !=null) ?null :

                    new KeySpliterator<>(map, lo, index = mid, est >>>=1,

                                        expectedModCount);

        }

public void forEachRemaining(Consumer<? super K> action) {

            int i, hi, mc;

            if (action ==null)

                throw new NullPointerException();

            HashMap<K,V> m =map;

            Node<K,V>[] tab = m.table;

            if ((hi =fence) <0) {

                mc =expectedModCount = m.modCount;

                hi =fence = (tab ==null) ?0 : tab.length;

            }

            else

                mc =expectedModCount;

            if (tab !=null && tab.length >= hi &&

                    (i =index) >=0 && (i < (index = hi) ||current !=null)) {

                Node<K,V> p =current;

                current =null;

                do {

                        if (p ==null)

                        p = tab[i++];

                    else {

                        action.accept(p.key);

                        p = p.next;

                    }

                }while (p !=null || i < hi);

                if (m.modCount != mc)

                        throw new ConcurrentModificationException();

                }

    }

public boolean tryAdvance(Consumer<? super K> action) {

                int hi;

                if (action ==null)

                        throw new NullPointerException();

                Node<K,V>[] tab =map.table;

                if (tab !=null && tab.length >= (hi = getFence()) &&index >=0) {

                    while (current !=null ||index < hi) {

                            if (current ==null)

                                    current = tab[index++];

                            else {

                                K k =current.key;

                                current =current.next;

                                action.accept(k);

                              if (map.modCount !=expectedModCount)

                                    throw new ConcurrentModificationException();

                                return true;

                    }

            }

        }

        return false;

    }

    public int characteristics() {

        return (fence <0 ||est ==map.size ? Spliterator.SIZED :0) | Spliterator.DISTINCT;

        }

}

static final class ValueSpliterator<K,V> extends HashMapSpliterator<K,V>

implements Spliterator<V> {

ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est,

                        int expectedModCount) {

                super(m, origin, fence, est, expectedModCount);

        }

public ValueSpliterator<K,V> trySplit() {

            int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

            return (lo >= mid ||current !=null) ?null :

                        new ValueSpliterator<>(map, lo, index = mid, est >>>=1,

                                expectedModCount);

        }

public void forEachRemaining(Consumer<? super V> action) {

                int i, hi, mc;

            if (action ==null)

                    throw new NullPointerException();

            HashMap<K,V> m =map;

            Node<K,V>[] tab = m.table;

            if ((hi =fence) <0) {

                mc =expectedModCount = m.modCount;

                hi =fence = (tab ==null) ?0 : tab.length;

            }

            else

                mc =expectedModCount;

            if (tab !=null && tab.length >= hi &&

                        (i =index) >=0 && (i < (index = hi) ||current !=null)) {

                 Node<K,V> p =current;

                current =null;

                do {

                    if (p ==null)

                            p = tab[i++];

                    else {

                        action.accept(p.value);

                        p = p.next;

                    }

                }while (p !=null || i < hi);

                if (m.modCount != mc)

                        throw new ConcurrentModificationException();

                }

    }

public boolean tryAdvance(Consumer<? super V> action) {

            int hi;

            if (action ==null)

                        throw new NullPointerException();

            Node[] tab =map.table;

            if (tab !=null && tab.length >= (hi = getFence()) &&index >=0) {

                    while (current !=null ||index < hi) {

                            if (current ==null)

                                current = tab[index++];

                            else {

                                V v =current.value;

                                current =current.next;

                                action.accept(v);

                                if (map.modCount !=expectedModCount)

                                        throw new ConcurrentModificationException();

                                return true;

                            }

                    }

            }

            return false;

        }

public int characteristics() {

                return (fence <0 ||est ==map.size ? Spliterator.SIZED :0);

        }

}


static final class EntrySpliterator<K,V>extends HashMapSpliterator<K,V>

implements Spliterator<K,V> {

EntrySpliterator(HashMap<K,V> m, int origin, int fence, int est,

                        int expectedModCount) {

super(m, origin, fence, est, expectedModCount);

        }

public EntrySpliterator<K,V> trySplit() {

              int hi = getFence(), lo =index, mid = (lo + hi) >>>1;

            return (lo >= mid ||current !=null) ?null :

            new EntrySpliterator<>(map, lo, index = mid, est >>>=1, expectedModCount);

        }

public void forEachRemaining(Consumer<? super Map.Entry<K,V> action) {

            int i, hi, mc;

            if (action ==null)

                    throw new NullPointerException();

            HashMap<K,V> m =map;

            Node<K,V>[] tab = m.table;

            if ((hi =fence) <0) {

                mc =expectedModCount = m.modCount;

                hi =fence = (tab ==null) ?0 : tab.length;

            }

            else

                mc =expectedModCount;

                 if (tab !=null && tab.length >= hi &&(i =index) >=0

                        && (i < (index = hi) ||current !=null)) {

                        Node<K,V> p =current;

                        current =null;

                        do {

                            if (p ==null)

                                p = tab[i++];

                            else {

                                    action.accept(p);

                                    p = p.next;

                                }

                            }while (p !=null || i < hi);

                                if (m.modCount != mc)

                                        throw new ConcurrentModificationException();

                        }

        }

public boolean tryAdvance(Consumer<? super Map<K,V>> action) {

int hi;

            if (action ==null)

                    throw new NullPointerException();

            Node<K,V>[] tab =map.table;

            if (tab !=null && tab.length >= (hi = getFence()) &&index >=0) {

                while (current !=null ||index < hi) {

                            if (current ==null)

                                current = tab[index++];

                            else {

                                Node<K,V> e =current;

                                current =current.next;

                                action.accept(e);

                                if (map.modCount !=expectedModCount)

                                        throw new ConcurrentModificationException();

                                return true;

                        }

                }

        }

        return false;

        }

public int characteristics() {

            return (fence <0 ||est ==map.size ? Spliterator.SIZED :0) | Spliterator.DISTINCT;

        }

}


    Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {

            return new Node<>(hash, key, value, next);

    }

    Node<K,V> replacementNode(Node<K,V> p, Node next) {

                return new Node<>(p.hash, p.key, p.value, next);

    }


    TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {

            return new TreeNode<>(hash, key, value, next);

    }


    TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {

            return new TreeNode<>(p.hash, p.key, p.value, next);

    }

    void reinitialize() {

        table =null;

        entrySet =null;

        keySet =null;

        values =null;

        modCount =0;

        threshold =0;

        size =0;

    }

回调函数

    void afterNodeAccess(Node<K,V> p) { }

void afterNodeInsertion(boolean evict) { }

void afterNodeRemoval(Node<K,V> p) { }

// Called only from writeObject, to ensure compatible ordering.

    void internalWriteEntries(java.io.ObjectOutputStream s)throws IOException {

        Node<K,V>[] tab;

        if (size >0 && (tab =table) !=null) {

                for (int i =0; i < tab.length; ++i) {

                        for (Node e = tab[i]; e !=null; e = e.next) {

                            s.writeObject(e.key);

                            s.writeObject(e.value);

                        }

                }

        }

}

红黑树

    static final class TreeNodeextends LinkedHashMap.Entry {

        TreeNode<K,V> parent;  // red-black tree links

        TreeNode<K,V> left;

        TreeNode<K,V> right;

        TreeNode<K,V> prev;    // needed to unlink next upon deletion

        boolean red;

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

                super(hash, key, val, next);

        }

//返回跟节点

        final TreeNoderoot() {

                    for (TreeNode r =this, p;;) {

                            if ((p = r.parent) ==null)  return r;

                        r = p;

                    }

            }

//确保给定的根是它的bin的第一个节点。

        static void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {

             int n;

            if (root !=null && tab !=null && (n = tab.length) >0) {

                 int index = (n -1) & root.hash;

                TreeNode<K,V> first = (TreeNode<K,V>)tab[index];

                if (root != first) {

                    Node<K,V> rn;

                    tab[index] = root;

                    TreeNode<K,V> rp = root.prev;

                    if ((rn = root.next) !=null)

                        ((TreeNode<K,V>)rn).prev = rp;

                    if (rp !=null)

                         rp.next = rn;

                    if (first !=null)

                        first.prev = root;

                    root.next = first;

                    root.prev =null;

                }

                assert checkInvariants(root);

            }

}

//在树中查找某个节点

        final TreeNode<K,V > find(int h, Object k, Class kc) {

            TreeNode<K,V> p =this;

            do {

                int ph, dir; K pk;

                TreeNode<K,V> pl = p.left, pr = p.right, q;

                if ((ph = p.hash) > h)

                        p = pl;

                else if (ph < h)

                        p = pr;

                else if ((pk = p.key) == k || (k !=null && k.equals(pk)))

                                    return p;

                else if (pl ==null)

                                p = pr;

                else if (pr ==null)

                        p = pl;

                else if ((kc !=null || (kc =comparableClassFor(k)) !=null) &&

                        (dir =compareComparables(kc, k, pk)) !=0)

                        p = (dir <0) ? pl : pr;

                else if ((q = pr.find(h, k, kc)) !=null)

                        return q;

                else

                        p = pl;

                }while (p !=null);

               return null;

        }

//按照hashCode和Key查找

        final TreeNodegetTreeNode(int h, Object k) {

                        return ((parent !=null) ? root() :this).find(h, k, null);

        }

//tieBreakOrder()方法最终还是通过调用System.identityHashCode()方法来比较。

        static int tieBreakOrder(Object a, Object b) {

            int d;

            if (a ==null || b ==null ||

                        (d = a.getClass().getName().compareTo(b.getClass().getName())) ==0)

                d = (System.identityHashCode(a) <= System.identityHashCode(b) ?-1 :1);

            return d;

        }

//将链表转化为树

       final void treeify(Node<K,V>[] tab) {

            TreeNode<K,V> root =null;

            for (TreeNode<K,V> x =this, next; x !=null; x = next) {

                next = (TreeNode<K,V>)x.next;

                x.left = x.right =null;

                if (root ==null) {

                    x.parent =null;

                    x.red =false;

                    root = x;

                }

                else {

                    K k = x.key;

                    int h = x.hash;

                    Class kc =null;

                    for (TreeNode<K,V> p = root;;) {

                         int dir, ph;

                        K pk = p.key;

                        if ((ph = p.hash) > h)

                            dir = -1;

                        else if (ph < h)

                            dir =1;

                        else if ((kc ==null &&(kc =comparableClassFor(k)) ==null) ||

                                (dir =compareComparables(kc, k, pk)) ==0)

                            dir =tieBreakOrder(k, pk);

                        TreeNode<K,V> xp = p;

                        if ((p = (dir <=0) ? p.left : p.right) ==null) {

                                x.parent = xp;

                                if (dir <=0) xp.left = x;

                                 else xp.right = x;

                                 root =balanceInsertion(root, x);

                                break;

                        }

                }

                }

            }

            moveRootToFront(tab, root);

        }

//将树转化为链表,返回头节点

        final Node<K,V> untreeify(HashMap<K,V> map) {

            Node<K,V> hd =null, tl =null;

            for (Node<K,V> q =this; q !=null; q = q.next) {

                    Node<K,V> p = map.replacementNode(q, null);

                if (tl ==null)    hd = p;

                 else  tl.next = p;

                tl = p;

            }

        return hd;

        }

//树版的插入操作

        final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab,

                                      int h, K k, V v) {

            Class kc =null;

            boolean searched =false;

            TreeNode<K,V> root = (parent !=null) ? root() :this;

            for (TreeNode<K,V> p = root;;) {

                int dir, ph; K pk;

                if ((ph = p.hash) > h)

                      dir = -1;

                else if (ph < h)

                        dir =1;

                else if ((pk = p.key) == k || (k !=null && k.equals(pk)))

                            return p;

                else if ((kc ==null &&(kc =comparableClassFor(k)) ==null) ||

                            (dir =compareComparables(kc, k, pk)) ==0) {

                        if (!searched) {

                            TreeNode<K,V> q, ch;

                            searched =true;

                                if (((ch = p.left) !=null &&(q = ch.find(h, k, kc)) !=null) ||

                                    ((ch = p.right) !=null &&(q = ch.find(h, k, kc)) !=null))

                                      return q;

                    }

                dir =tieBreakOrder(k, pk);

                }

                TreeNode<K,V> xp = p;

                if ((p = (dir <=0) ? p.left : p.right) ==null) {

                    Node<K,V> xpn = xp.next;

                    TreeNode x = map.newTreeNode(h, k, v, xpn);

                    if (dir <=0)  xp.left = x;

                      else   xp.right = x;

                    xp.next = x;

                    x.parent = x.prev = xp;

                    if (xpn !=null)((TreeNode<K,V>)xpn).prev = x;

                    moveRootToFront(tab, balanceInsertion(root, x));

                    return null;

                }

        }

}

//删除树的节点

        final void removeTreeNode(HashMap<K,V> map, Node<K,V>[] tab,

                                  boolean movable) {

               int n;

            if (tab ==null || (n = tab.length) ==0) return;

            int index = (n -1) & hash;

            TreeNode<K,V> first = (TreeNode<K,V>)tab[index], root = first, rl;

            TreeNode<K,V> succ = (TreeNode<K,V>)next, pred =prev;

            if (pred ==null)

                tab[index] = first = succ;

            else

                pred.next = succ;

            if (succ !=null)

                    succ.prev = pred;

            if (first ==null)

                return;

            if (root.parent !=null)

                    root = root.root();

            if (root ==null || root.right ==null ||(rl = root.left) ==null || rl.left ==null) {

                    tab[index] = first.untreeify(map);  // too small

                return;

            }

            TreeNode<K,V> p =this, pl =left, pr =right, replacement;

            if (pl !=null && pr !=null) {

                TreeNode<K,V> s = pr, sl;

                while ((sl = s.left) !=null)// find successor

                    s = sl;

                boolean c = s.red; s.red = p.red; p.red = c; // swap colors

                TreeNode<K,V> sr = s.right;

                TreeNode<K,V> pp = p.parent;

                if (s == pr) {// p was s's direct parent

                    p.parent = s;

                    s.right = p;

                }

                else {

                    TreeNode<K,V> sp = s.parent;

                    if ((p.parent = sp) !=null) {

                        if (s == sp.left)  sp.left = p;

                        else  sp.right = p;

                    }

                    if ((s.right = pr) !=null)   pr.parent = s;

                  }

                  p.left =null;

                if ((p.right = sr) !=null)

                        sr.parent = p;

                if ((s.left = pl) !=null)

                        pl.parent = s;

                if ((s.parent = pp) ==null)

                        root = s;

                else if (p == pp.left)

                        pp.left = s;

                else

                    pp.right = s;

                if (sr !=null)

                        replacement = sr;

                else

                    replacement = p;

            }

            else if (pl !=null) replacement = pl;

            else if (pr !=null) replacement = pr;

            else replacement = p;

            if (replacement != p) {

                 TreeNode<K,V> pp = replacement.parent = p.parent;

                if (pp ==null)  root = replacement;

                else if (p == pp.left)   pp.left = replacement;

                   else pp.right = replacement;

                p.left = p.right = p.parent =null;

            }

            TreeNode<K,V> r = p.red ? root :balanceDeletion(root, replacement);

            if (replacement == p) {// detach

                TreeNode<K,V> pp = p.parent;

                p.parent =null;

                if (pp !=null) {

                    if (p == pp.left)  pp.left =null;

                    else if (p == pp.right) pp.right =null;

                }

        }

            if (movable) moveRootToFront(tab, r);

        }

//拆分树

        final void split(HashMap map, Node[] tab, int index, int bit) {

            TreeNode b =this;

            // Relink into lo and hi lists, preserving order

            TreeNode loHead =null, loTail =null;

            TreeNode hiHead =null, hiTail =null;

            int lc =0, hc =0;

            for (TreeNode e = b, next; e !=null; e = next) {

                 next = (TreeNode)e.next;

                e.next =null;

                if ((e.hash & bit) ==0) {

                    if ((e.prev = loTail) ==null) loHead = e;

                    else loTail.next = e;

                    loTail = e;

                    ++lc;

                }

            else {

                    if ((e.prev = hiTail) ==null) hiHead = e;

                    else hiTail.next = e;

                    hiTail = e;

                    ++hc;

                }

            }

        if (loHead !=null) {

                    if (lc <=UNTREEIFY_THRESHOLD) tab[index] = loHead.untreeify(map);

                    else {

                       tab[index] = loHead;

                    if (hiHead !=null)// (else is already treeified)

                        loHead.treeify(tab);

                }

            }

            if (hiHead !=null) {

                if (hc <=UNTREEIFY_THRESHOLD)

                        tab[index + bit] = hiHead.untreeify(map);

                else {

                    tab[index + bit] = hiHead;

                    if (loHead !=null) hiHead.treeify(tab);

                }

        }

    }

//红黑树平衡方法

//左旋

        static<K,V>  TreeNode<K,V> rotateLeft(TreeNode<K,V> root, TreeNode<K,V> p) {

            TreeNode r, pp, rl;

            if (p !=null && (r = p.right) !=null) {

                    if ((rl = p.right = r.left) !=null)  rl.parent = p;

                    if ((pp = r.parent = p.parent) ==null) (root = r).red =false;

                    else if (pp.left == p) pp.left = r;

                    else pp.right = r;

                    r.left = p;

                    p.parent = r;

                }

            return root;

        }

//右旋

static TreeNode rotateRight(TreeNode root,TreeNode p) {

            TreeNode l, pp, lr;

            if (p !=null && (l = p.left) !=null) {

                        if ((lr = p.left = l.right) !=null) lr.parent = p;

                        if ((pp = l.parent = p.parent) ==null) (root = l).red =false;

                        else if (pp.right == p) pp.right = l;

                        else pp.left = l;

                        l.right = p;

                    p.parent = l;

                }

            return root;

        }

//平衡

static TreeNode balanceInsertion(TreeNode root, TreeNode x) {

                x.red =true;

            for (TreeNode xp, xpp, xppl, xppr;;) {

                    if ((xp = x.parent) ==null) {

                                x.red =false;

                                return x;

                }

                else if (!xp.red || (xpp = xp.parent) ==null) return root;

                    if (xp == (xppl = xpp.left)) {

                        if ((xppr = xpp.right) !=null && xppr.red) {

                            xppr.red =false;

                            xp.red =false;

                            xpp.red =true;

                            x = xpp;

                    }else {

                        if (x == xp.right) {

                            root =rotateLeft(root, x = xp);

                            xpp = (xp = x.parent) ==null ?null : xp.parent;

                        }

                    if (xp !=null) {

                            xp.red =false;

                            if (xpp !=null) {

                                xpp.red =true;

                                root =rotateRight(root, xpp);

                            }

                        }

                    }

                }else {

                        if (xppl !=null && xppl.red) {

                            xppl.red =false;

                            xp.red =false;

                            xpp.red =true;

                            x = xpp;

                        }else {

                            if (x == xp.left) {

                                root =rotateRight(root, x = xp);

                                xpp = (xp = x.parent) ==null ?null : xp.parent;

                            }

                            if (xp !=null) {

                                    xp.red =false;

                                    if (xpp !=null) {

                                        xpp.red =true;

                                        root =rotateLeft(root, xpp);

                                    }

                                }

                            }

                        }

                    }

        }


static TreeNode balanceDeletion(TreeNode root, TreeNode x) {

for (TreeNode xp, xpl, xpr;;)  {

            if (x ==null || x == root) return root;

             else if ((xp = x.parent) ==null) {

                    x.red =false;

                    return x;

                }else if (x.red) {

                    x.red =false;

                    return root;

                }else if ((xpl = xp.left) == x) {

                        if ((xpr = xp.right) !=null && xpr.red) {

                            xpr.red =false;

                            xp.red =true;

                            root =rotateLeft(root, xp);

                            xpr = (xp = x.parent) ==null ?null : xp.right;

                    }

                    if (xpr ==null)  x = xp;

                    else {

                        TreeNode sl = xpr.left, sr = xpr.right;

                        if ((sr ==null || !sr.red) &&(sl ==null || !sl.red)) {

                            xpr.red =true;

                            x = xp;

                        }else {

                                if (sr ==null || !sr.red) {

                                        if (sl !=null)sl.red =false;

                                xpr.red =true;

                                root =rotateRight(root, xpr);

                                xpr = (xp = x.parent) ==null ?null : xp.right;

                            }

                            if (xpr !=null) {

                                xpr.red = (xp ==null) ?false : xp.red;

                                if ((sr = xpr.right) !=null) sr.red =false;

                            }

                            if (xp !=null) {

                                xp.red =false;

                                root =rotateLeft(root, xp);

                            }

                            x = root;

                        }

                    }

                }else {// symmetric

                    if (xpl !=null && xpl.red) {

                        xpl.red =false;

                        xp.red =true;

                        root =rotateRight(root, xp);

                        xpl = (xp = x.parent) ==null ?null : xp.left;

                    }

                    if (xpl ==null) x = xp;

                    else {

                        TreeNode sl = xpl.left, sr = xpl.right;

                        if ((sl ==null || !sl.red) &&(sr ==null || !sr.red)) {

                            xpl.red =true;

                            x = xp;

                        }else {

                                if (sl ==null || !sl.red) {

                                        if (sr !=null) sr.red =false;

                                xpl.red =true;

                                root =rotateLeft(root, xpl);

                                xpl = (xp = x.parent) ==null ?null : xp.left;

                            }

                            if (xpl !=null) {

                                xpl.red = (xp ==null) ?false : xp.red;

                                if ((sl = xpl.left) !=null) sl.red =false;

                            }

                            if (xp !=null) {

                                xp.red =false;

                                root =rotateRight(root, xp);

                            }

                            x = root;

                        }

                }

            }

        }

}

//递归不变检查,检测稳定性

        static boolean checkInvariants(TreeNode t) {

            TreeNode tp = t.parent, tl = t.left, tr = t.right,

                tb = t.prev, tn = (TreeNode)t.next;

            if (tb !=null && tb.next != t) return false;

            if (tn !=null && tn.prev != t) return false;

            if (tp !=null && t != tp.left && t != tp.right) return false;

            if (tl !=null && (tl.parent != t || tl.hash > t.hash)) return false;

            if (tr !=null && (tr.parent != t || tr.hash < t.hash)) return false;

            if (t.red && tl !=null && tl.red && tr !=null && tr.red) return false;

            if (tl !=null && !checkInvariants(tl)) return false;

            if (tr !=null && !checkInvariants(tr)) return false;

            return true;

        }

    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容