#集合源码学习

1、ArrayList

1.1 类属性

    /**
     * Default initial capacity. 默认初始容量
     */
    private static final int DEFAULT_CAPACITY = 10;

	/**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    // 默认容量的空的数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * 存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度。添加第一个元素时,
     * elementData==DEFAULTCAPACITY_empty_elementData的任何空ArrayList都将扩展为DEFAULT_CAPACITY。
     */
    transient Object[] elementData;

	/**
     * 集合大小,初始默认值为0
     * @serial
     */
    private int size;

1.2 构造方法

	/**
	 * 无参构造方法
     * Constructs an empty list with an initial capacity of ten.
     * 构造一个初始容量为10的空的集合,但是在集合初始化时,是一个空数组
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  集合初始容量
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        // >0, 则按照实际容量创建新的数组
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            // =0, 则将初始属性空数组赋给elementData
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            // <0, 抛出非法容量异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

1.3 add()方法执行

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    // 将元素添加到数组中
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    // 如果element是默认初始容量的数组,即第一次添加数据
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        // 在DEFAULT_CAPACITY(10)和传入的minCapacity(1)获取最大值传给minCapacity
        minCapacity = Math.max(DEFAULT_CAPACITY(10), minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++; //记录集合被修改的次数

    // 需要最小容量 - 当前数组容量 > 0时, 说明当前数组不够大,进行数组扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // 获取原数组长度,注意:第一次添加元素时,该值为0
    int oldCapacity = elementData.length;
    // 扩容后数组长度,为当前数组长度的1.5倍,第一次添加元素时,此处为0
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        //如果扩容之后数组长度仍然小于所需最小容量,则将所需最小容量赋值给新数组长度
        //注意:第一次添加元素时,进行数组扩容,此时minCapacity是DEFAULT_CAPACITY(10)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        // 如果大于数组最大长度,则返回Integer.MAX_VALUE,否则返回MAX_ARRAY_SIZE
        newCapacity = hugeCapacity(minCapacity);
    // 将原数组复制到新的数组中
    elementData = Arrays.copyOf(elementData, newCapacity);
}

// 数组最大值,超过会报内存溢出
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
    MAX_ARRAY_SIZE;
}

1.4 总结:

  1. ArrayList中维护一个Object类型的数组用来存储数据
  2. 无参构造创建集合时,初始elementData数组容量为0,当第一次添加时,数组才会扩容到默认初始容量10。之后扩容倍数为原来数组长度的1.5倍。
  3. 如果使用有参构造创建,则elementData容量为指定大小,如需扩容,扩容为原来的1.5倍

2、LinkedList

2.1 内部类

private static class Node<E> {
    // 存储的数据
    E item;
    
    // 下一个节点
    Node<E> next;
    
    // 前一个节点
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

2.2 类属性

transient int size = 0;

transient Node<E> first;

transient Node<E> last;

2.3 构造方法

/**
 * Constructs an empty list.
 */
public LinkedList() {
}

public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

2.4 add()方法

public boolean add(E e) {
    linkLast(e);
    return true;
}

/**
 * Links e as last element.
 * 将新节点连接到链表后面
 */
void linkLast(E e) {
    // 创建一个临时节点l, 指向last。第一次添加时last为null, 即l为null
    final Node<E> l = last;
    // 创建一个新的节点,prev指向l, next指向null
    final Node<E> newNode = new Node<>(l, e, null);
    // last节点指向新的节点
    last = newNode;
    if (l == null)
        // 如果l节点为null, first节点指向newNode节点。第一次为null
        first = newNode;
    else
        // 否则的话,l的下一个节点指向新的节点
        l.next = newNode;
    size++;
    modCount++;
}

2.5 总结:

  1. LinkedList底层维护了一个双向列表
  2. LinkedList中维护了两个属性first和last,分别指向头节点和尾节点
  3. 每个节点对象中,维护了prev、next、item三个属性,分别指向前一个节点、下一个节点和自身存储数据

3、HashSet

底层是由HashMap实现的,所以它的源码其实主要就是看HashMap源码

3.1 类属性

private transient HashMap<E,Object> map;

// 作为map的value一个虚拟值
private static final Object PRESENT = new Object();

3.2 构造方法

public HashSet() {
    map = new HashMap<>();
}

3.3 add方法

public boolean add(E e) {
    // e为添加的值, PRESENT为属性中初始化的object,在这里其实就是去map中给value占个值
    return map.put(e, PRESENT)==null;
}

4、LinkedHashSet

LinkedHashSet继承自HashSet

4.1 构造方法

public LinkedHashSet() {
    // 初始容量16, 加载因子0.75,第三个参数用来区别于其他构造行数
    super(16, .75f, true);
}

// hashSet中构造方法dummy:笨蛋, 用来区别于其他构造函数
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

4.1总结

  1. LinkedHashSet是HashSet子类,是由LinkedHashMap实现的。
  2. 底层维护了一个哈希表+双向链表,双向链表用来保证数据插入和取出的次序

5、TreeSet

public TreeSet() {
    this(new TreeMap<>());
}

5.1 总结

TreeSe底层是由TreeMap实现的。底层是由红黑树实现

6、HashMap

6.1 内部类

/*
 * 链表节点
 */
static class Node<K,V> implements Map.Entry<K,V> {
    // 节点hash
    final int hash;
    // map key值
    final K key;
    // map value值
    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 final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
        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);
        }

        /**
         * Returns root of tree containing this node.
         */
        final TreeNode<K,V> root() {
            for (TreeNode<K,V> r = this, p;;) {
                if ((p = r.parent) == null)
                    return r;
                r = p;
            }
        }

6.2 类属性

/**
 * 默认初始容量 16,必须为2的幂
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

/**
 * 最大容量,如果指定容量大于这个数,则使用这个值
 */
static final int MAXIMUM_CAPACITY = 1 << 30;

/**
 * 默认加载因子0.75
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
 * 当链表节点为8时,转为红黑树
 */
static final int TREEIFY_THRESHOLD = 8;

/**
 * 当节点小于6时,将树转为链表
 */
static final int UNTREEIFY_THRESHOLD = 6;

/**
 * 最小转为树的容量 64
 */
static final int MIN_TREEIFY_CAPACITY = 64;

/**
 * 维护的链表数组
 */
transient Node<K,V>[] table;

/**
 * 保存缓存的keySet()
 */
transient Set<Map.Entry<K,V>> entrySet;

// 集合大小
transient int size;

// 扩容临界值,达到临界值进行扩容操作
int threshold;

// 哈希表的加载因子
final float loadFactor;

6.3 构造方法

public HashMap() {
    // 无参构造默认加载因子0.75
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

6.4 put()方法

64public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

// 进行hash计算,获得一个int的hash值
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

/**
 *
 * @param hash hash for key
 * @param key the key
 * @param value the value to put
 * @param onlyIfAbsent 如果为true,则不改变原来的值
 * @param evict 如果为false, the table 则处于创建模式.
 * @return previous value, or null if none
 */
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    // 创建一个临时链表数组,后面会将类属性table进行赋值,这么做是为了避免重复去堆中进行属性获取。
    Node<K,V>[] tab;
    // 创建临时节点p
    Node<K,V> p;
    int n;
    int i;
    // 如果数组为null,或者数组长度为0,进行第一次扩容
    if ((tab = table) == null || (n = tab.length) == 0)
        // 数组长度赋给 n
        n = (tab = resize()).length;
    // i = (n - 1) & hash通过hash值计算元素应在放在数组的位置,然后对该位置进行判断是否为null
    if ((p = tab[i = (n - 1) & hash]) == null)
        // 如果该位置为null,则创建一个node节点放在数组该位置上
        tab[i] = newNode(hash, key, value, null);
    else {
        // 如果数组该位置不为null
        Node<K,V> e;
        K k;
        //先比较hash值是否相等,如果hash值相等,则比较key是否相等
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
            //如果hash值和key值都相等,将数组该位置链表首节点赋给e
            e = p;
        else if (p instanceof TreeNode)
            // p是红黑树
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            // p是链表
            for (int binCount = 0; ; ++binCount) {
                // 将链表下一节点赋给e,如果链表下一个节点为null,即是链表尾节点
                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;
                }
                // 如果数组此位置的节点的下一节点不为null,则将下一节点拿出来与该元素值进行比较,如果相等,直接退出循环,
                // 否则将下一节点赋值给p继续循环进行判断
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        // 放入了相同的key时
        if (e != null) { // existing mapping for key
            // 将原来node节点的value值
            V oldValue = e.value;
            // onlyIfAbsent传入为false,取反为真
            if (!onlyIfAbsent || oldValue == null)
                // 将要添加的value值赋给原来的value值
                e.value = value;
            afterNodeAccess(e);
            // 返回被覆盖的value值
            return oldValue;
        }
    }
    ++modCount;
    // 如果集合个数大于扩容临界值,则进行扩容
    if (++size > threshold)
        resize();
    // HashMap中该方法是一个空方法
    afterNodeInsertion(evict);
    return null;
}


 /**
  * 数组进行扩容
  */
final Node<K,V>[] resize() {
    Node<K,V>[] oldTab = table;
    // 第一次添加元素时,oldTable为null, oldCap为0
    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;
        }
        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 {   
        // 第一次添加元素时,newCap = 16
        newCap = DEFAULT_INITIAL_CAPACITY;
        // newThr = 0.75 * 16 = 12 临界值,当数组已经用到临界值时,进行扩容
        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"})
    // 实例化链表数组,第一次添加元素时newCap=16
    Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
    table = newTab;
    // 如果原数组不为Null
    if (oldTab != null) {
        // 遍历原来的链表数组
        for (int j = 0; j < oldCap; ++j) {
            Node<K,V> e;
            // 如果链表!=null, 将该位置链表首节点赋值给e
            if ((e = oldTab[j]) != null) {
                // 将原来位置设为Null
                oldTab[j] = null;
                // 如果首节点下一节点为null
                if (e.next == null)
                    // 将e放到新链表数组计算过的位置上
                    newTab[e.hash & (newCap - 1)] = e;
                // 如果e是红黑树
                else if (e instanceof TreeNode)
                    // 将树重新拆分
                    ((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;
}


/**
 * 将链表转换为红黑树
 */
final void treeifyBin(Node<K,V>[] tab, int hash) {
    int n, index;
    Node<K,V> e;
    // 判断链表数组是否为null或者数组长度是否<64, n为数组长度
    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
        // 扩容
        resize();
    // 判断数组最后一个位置不等于null, 进行红黑树转换,
    else if ((e = tab[index = (n - 1) & hash]) != null) {
        TreeNode<K,V> hd = null, tl = null;
        do {
            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);
    }
}

// For treeifyBin
TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
    return new TreeNode<>(p.hash, p.key, p.value, next);
}

6.5 总结

  1. 底层维护一个链表数组table,有两个内部类Node和TreeNode
  2. 默认初始容量为16,加载因子为0.75,构造器实例化的时候数组并没有实例化,当第一次添加集合元素时,进行扩容,数组大小才确定为16,之后每次使用到临界值的时候,即原数组长度*加载因子,扩容为原数组的两倍。
  3. 当集合大小>64并且链表长度>=8时,链表会自动转为红黑树

7、LinkedHashMap

LinkedHashMap继承自HashMap

7.1 内部类

/**
 * HashMap.Node subclass for normal LinkedHashMap entries.
 */
static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

7.2 类属性

/**
 * 双向链表头节点
 */
transient LinkedHashMap.Entry<K,V> head;

/**
 * 双向链表的尾节点
 */
transient LinkedHashMap.Entry<K,V> tail;

/**
 * 此链接哈希图的迭代排序方法:true表示访问顺序,false表示插入顺序。
 *
 * @serial
 */
final boolean accessOrder;

7.3 构造方法

public LinkedHashMap() {
    super();
    accessOrder = false;
}

public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

7.4 put()方法

// 调用的是HashMap中的方法,LinkedHashMap中put的区别在于afterNodeInsertion(evict)这个方法
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

// putVal()方法中newNode会调用LinkedHashMap中的newNode()方法
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
    LinkedHashMap.Entry<K,V> p =
        new LinkedHashMap.Entry<K,V>(hash, key, value, e);
    linkNodeLast(p);
    return p;
}

// link at the end of list
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
    // 将双向链表尾节点给last
    LinkedHashMap.Entry<K,V> last = tail;
    // 把新创建的p节点给尾节点
    tail = p;
    // 第一次添加的时候,last为null
    if (last == null)
        // 第一次添加元素的时候,头节点指向添加的节点
        head = p;
    else {
        //添加节点的前一个节点指向last
        p.before = last;
        
        last.after = p;
    }
}

// afterNodeInsertion(evict)在hashmap类中是空实现,LinkedHashMap中覆写了这个方法
void afterNodeInsertion(boolean evict) { // evict传入的是true
    LinkedHashMap.Entry<K,V> first;
    if (evict && (first = head) != null && removeEldestEntry(first)) {
        K key = first.key;
        removeNode(hash(key), key, null, false, true);
    }
}

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
    return false;
}

7.5 总结

  1. LinkedHashMap继承自HashMap类,重写了newCode()等方法。
  2. 底层维护了数组table + Entry双向链表.

8、TreeMap

8.1 内部类

static final class Entry<K,V> implements Map.Entry<K,V> {
    K key;
    V value;
    // 左节点
    Entry<K,V> left;
    // 右节点
    Entry<K,V> right;
    // 父节点
    Entry<K,V> parent;
    boolean color = BLACK;

    /**
     * Make a new cell with given key, value, and parent, and with
     * {@code null} child links, and BLACK color.
     */
    Entry(K key, V value, Entry<K,V> parent) {
        this.key = key;
        this.value = value;
        this.parent = parent;
    }

    /**
     * Returns the key.
     *
     * @return the key
     */
    public K getKey() {
        return key;
    }

    /**
     * Returns the value associated with the key.
     *
     * @return the value associated with the key
     */
    public V getValue() {
        return value;
    }

    /**
     * Replaces the value currently associated with the key with the given
     * value.
     *
     * @return the value associated with the key before this method was
     *         called
     */
    public V setValue(V value) {
        V oldValue = this.value;
        this.value = value;
        return oldValue;
    }

    public boolean equals(Object o) {
        if (!(o instanceof Map.Entry))
            return false;
        Map.Entry<?,?> e = (Map.Entry<?,?>)o;

        return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
    }

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

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

8.2 类属性

/**
 * 比较器
 */
private final Comparator<? super K> comparator;

private transient Entry<K,V> root;

/**
 * 树的节点数
 */
private transient int size = 0;

/**
 * The number of structural modifications to the tree.
 */
private transient int modCount = 0;

// Red-black mechanics
private static final boolean RED   = false;
private static final boolean BLACK = true;

8.3 构造方法

public TreeMap() {
    comparator = null;
}

public TreeMap(Comparator<? super K> comparator) {
    this.comparator = comparator;
}

8.4 put()方法

public V put(K key, V value) {
    //根节点给t
    Entry<K,V> t = root;
    // 根节点为null, 第一次添加元素
    if (t == null) {
        compare(key, key); // type (and possibly null) check
        // 创建根节点
        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    // 不是第一次添加
    int cmp;
    Entry<K,V> parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    // 如果比较器不为null
    if (cpr != null) {
        do {
            // 将根节点给parent
            parent = t;
            // 比较添加节点和父节点key值
            cmp = cpr.compare(key, t.key);
            // 如果小,将左子节点给父节点循环遍历
            if (cmp < 0)
                t = t.left;
            // 如果大,将右子节点给父节点进行循环遍历
            else if (cmp > 0)
                t = t.right;
            else
                // 如果相等,值进行覆盖
                return t.setValue(value);
        } while (t != null);
    }
    // 没传入比较器
    else {
        // 如果添加的Key为null, 报空指针异常
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            // 调用实现Comparable父接口向上转型
            Comparable<? super K> k = (Comparable<? super K>) key;
        do {
            // 第一次是将根节点给父节点
            parent = t;
            // 进行比较
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    // 以传入的key,value 创建新的Entry节点
    Entry<K,V> e = new Entry<>(key, value, parent);
    if (cmp < 0)
        // 如果小,放左子节点
        parent.left = e;
    else
        // 如果大,放右子节点
        parent.right = e;
    fixAfterInsertion(e);
    size++;
    modCount++;
    return null;
}

// 节点插入之后,按照红黑树规则进行调整
private void fixAfterInsertion(Entry<K,V> x) {
    x.color = RED;

    while (x != null && x != root && x.parent.color == RED) {
        if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
            Entry<K,V> y = rightOf(parentOf(parentOf(x)));
            if (colorOf(y) == RED) {
                setColor(parentOf(x), BLACK);
                setColor(y, BLACK);
                setColor(parentOf(parentOf(x)), RED);
                x = parentOf(parentOf(x));
            } else {
                if (x == rightOf(parentOf(x))) {
                    x = parentOf(x);
                    rotateLeft(x);
                }
                setColor(parentOf(x), BLACK);
                setColor(parentOf(parentOf(x)), RED);
                rotateRight(parentOf(parentOf(x)));
            }
        } else {
            Entry<K,V> y = leftOf(parentOf(parentOf(x)));
            if (colorOf(y) == RED) {
                setColor(parentOf(x), BLACK);
                setColor(y, BLACK);
                setColor(parentOf(parentOf(x)), RED);
                x = parentOf(parentOf(x));
            } else {
                if (x == leftOf(parentOf(x))) {
                    x = parentOf(x);
                    rotateRight(x);
                }
                setColor(parentOf(x), BLACK);
                setColor(parentOf(parentOf(x)), RED);
                rotateLeft(parentOf(parentOf(x)));
            }
        }
    }
    root.color = BLACK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值