常见Collection集合分析

247 阅读18分钟

Collection集合

List

ArrayList

属性
// 默认初始化长度
private static final int DEFAULT_CAPACITY = 10;
// 空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 已构建的数组
transient Object[] elementData;
// 数组长度
private int size;
/** 
  * AbstractArrayList中对象,已经修改的次数
  * ArrayList 继承与 AbstractArrayList
  */
protected transient int modCount = 0;
初始化
// 1.无参构造 创建一个默认的空数组对象
public ArrayList() {
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

// 2.初始化长度构造 创建一个指定长度的数组对象
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        // 指定长度为0,则创建空数组对象
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

// 3.参数为集合的构造 
public ArrayList(Collection<? extends E> c) {
    // 将集合转换为数组对象
    Object[] a = c.toArray();
    if ((size = a.length) != 0) {
        // 集合若为ArrayList类型,则直接转换为当前对象
        if (c.getClass() == ArrayList.class) {
            elementData = a;
        } else {
            // 将转换后的数组复制,复制后的值构建为当前的ArrayList对象
            elementData = Arrays.copyOf(a, size, Object[].class);
        }
    } else {
        // replace with empty array.
        elementData = EMPTY_ELEMENTDATA;
    }
}
add方法
// 添加单个元素
public boolean add(E e) {
    /**
      * 1. 校验数组长度,并修改数组已被修改的值
      * 2. 新增元素添加到数组中
      */
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    // 将元素添加到最后一位可用空间中
    elementData[size++] = e;
    return true;
}
/**
  * 添加元素到指定的索引位置
  * 1.校验下标是否满足当前集合
  * 2.
  */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    // 将指定index下标及以后的元素向后移动
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    // 将index下标的值赋值到数组中
    elementData[index] = element;
    size++;
}

private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

数组新增前的校验和扩容操作:

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 返回数组的长度
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    // 校验当前数组是否为空数组对象
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        // 比较默认长度与当前最小长度,返回最大值
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
// 确保数组长度,若数组无可用长度,则需要将数组进行扩容
private void ensureExplicitCapacity(int minCapacity) {
    // 修改次数加1
    modCount++;
    // overflow-conscious code
    // 所需最小长度与当前数组的最大长度进行比较,判断是否需要对数组进行扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    // 当前数组的最大长度
    int oldCapacity = elementData.length;
    // 新数组的最大长度,对当前数组进行0.5倍的扩容
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        // 若长度超过可创建数组长度的最大值
        // 则返回可创建数组的最大值
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    // 将老数组中的数据拷贝到新创建的数组中
    elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
remove方法
// 删除数组中指定下标的元素
public E remove(int index) {
    // 校验当前下标是否超出数组的范围
    rangeCheck(index);
	// 数组被修改次数加 1
    modCount++;
    // 取出将要删除的值
    E oldValue = elementData(index);
	// 需要被删除的元素在数组中的下标值
    int numMoved = size - index - 1;
    if (numMoved > 0)
         // 将数组中指定index+1位置以后的元素像前移动
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    // 将数组中最后一位元素置为空,方便jvm回收
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
// 删除指定元素
public boolean remove(Object o) {
    if (o == null) {
        // 删除元素为空时,遍历数组,删除为空的元素
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        // 遍历数组,删除数组中指定的元素的值
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
} 
// 数组中删除元素的逻辑
private void fastRemove(int index) {
    // 数组被修改次数加 1
    modCount++;
    // 需要被删除的元素在数组中的下标值
    int numMoved = size - index - 1;
    if (numMoved > 0)
        // 将数组中指定index+1位置以后的元素像前移动
        System.arraycopy(elementData, index+1, elementData, index,numMoved);
    // 将数组中最后一位元素置为空,方便jvm回收
    elementData[--size] = null; // clear to let GC do its work
}

LinkedList

属性
// 链表长度
transient int size = 0;
// 首节点
transient Node<E> first;
// 尾节点
transient Node<E> last;
/** 
  * AbstractArrayList中对象,已经修改的次数
  * ArrayList 继承与 AbstractArrayList
  */
protected transient int modCount = 0;
初始化
// 无参构造,创建链表
public LinkedList() {}

// 含参数构造,参数为集合对象
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

// addAll方法,将集合数据添加到链表上
// 使用尾插法,依次添加
public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}

/**
  *  添加集合到链表中
  *
  * @param index 待插入结点的位置
  * @param c 需要插入的集合数据
  */
public boolean addAll(int index, Collection<? extends E> c) {
    // 判断指定结点位置是否满足在链表中
    checkPositionIndex(index);
	// 待插入集合转换为数组对象
    Object[] a = c.toArray();
    // 待插入数组的长度
    int numNew = a.length;
    if (numNew == 0)
        return false;
	// 临时节点,pre上一个节点,succ当前节点
    Node<E> pred, succ;
    // 插入结点位置为尾部结点
    if (index == size) {
        succ = null;
        pred = last;
    } else {
        // 插入结点位置为中间部分节点
        succ = node(index);
        pred = succ.prev;
    }
	
    // 遍历插入结点
    for (Object o : a) {
        @SuppressWarnings("unchecked") 
        E e = (E) o;
        // 创建新节点
        Node<E> newNode = new Node<>(pred, e, null);
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        // 新节点插入,指针向后移动
        pred = newNode;
    }

    // 将断开的链表链接到插入后的节点上
    if (succ == null) {
        last = pred;
    } else {
        pred.next = succ;
        succ.prev = pred;
    }
	// 修改链表长度
    size += numNew;
    // 修改集合修改次数
    modCount++;
    return true;
}
add方法
// 新增
public boolean add(E e) {
    linkLast(e);
    return true;
}
// 使用尾插法进行新增
void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}

// 在链表首部插入结点
 public void addFirst(E e) {
     linkFirst(e);
 }
// 使用头插法插入结点
private void linkFirst(E e) {
    final Node<E> f = first;
    final Node<E> newNode = new Node<>(null, e, f);
    first = newNode;
    if (f == null)
        last = newNode;
    else
        f.prev = newNode;
    size++;
    modCount++;
}
remove方法
空参删除:remove()

删除的节点为首节点数据

// 删除节点元素
public E remove() {
    return removeFirst();
}

// 删除首个节点元素
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}
删除第一个元素:removeFirst()
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}
首节点断链
// 将首节点与链表进行断链操作
 private E unlinkFirst(Node<E> f) {
     // assert f == first && f != null;
     final E element = f.item;
     final Node<E> next = f.next;
     f.item = null;
     f.next = null; // help GC
     first = next;
     if (next == null)
         last = null;
     else
         next.prev = null;
     size--;
     modCount++;
     return element;
 }
删除指定对象:remove(Object o)
// 删除链表中指定元素 
public boolean remove(Object o) {
    // 待删除元素是否为空 
    if (o == null) {
        // 从首节点依次遍历
         for (Node<E> x = first; x != null; x = x.next) {
             // 校验是否是待删除元素
             if (x.item == null) {
                 // 断链操作,进行删除
                 // 具体见断链操作
                 unlink(x);
                 return true;
             }
         }
     } else {
        // 待删除元素不为空
         for (Node<E> x = first; x != null; x = x.next) {
             // 校验是否为待删除元素
             if (o.equals(x.item)) {
                 // 断链操作,进行删除
                 // 具体见断链操作
                 unlink(x);
                 return true;
             }
         }
     }
     return false;
 }
删除指定位置元素:remove(int index)
 
public E remove(int index) {
    // 校验指定位置是否在链表中
    checkElementIndex(index);
     // 断链操作,进行删除
     // 具体见断链操作
     return unlink(node(index));
 }
private void checkElementIndex(int index) {
    if (!isElementIndex(index))
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

private boolean isElementIndex(int index) {
    return index >= 0 && index < size;
}

Node<E> node(int index) {
    // assert isElementIndex(index);
	// 判断当前位置是在前半部分还是后半部分
    // 遍历链表进行查找元素
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}
断链操作
// 断链删除元素 
// x节点不为空
E unlink(Node<E> x) {
    // assert x != null;
    // 当前节点值
    final E element = x.item;
    // 当前节点的下一个节点
    final Node<E> next = x.next;
    // 当前节点的上一个节点
    final Node<E> prev = x.prev;
	// 当前节点的上一个节点为空,则当前节点为首节点
    if (prev == null) {
        // 将下一个节点置为首节点
        first = next;
    } else {
        // 将当前节点的上一个节点的next指针指向当前节点的下一个节点
        // (图解:微信图片_20210316145013.png)
        prev.next = next;
        x.prev = null;
    }
	// 当前节点的下一个节点为空,则当前节点为尾节点
    if (next == null) {
        // 将上一个节点置为尾部节点
        last = prev;
    } else {
        // 将当前节点的
        // 图解:(微信图片_2021031614501.png)
        next.prev = prev;
        x.next = null;
    }
 
    x.item = null;
    size--;
    modCount++;
    return element;
}
删除尾结点:removeLast()
 public E removeLast() {
     final Node<E> l = last;
     if (l == null)
         throw new NoSuchElementException();
     return unlinkLast(l);
 }
// 尾结点断链操作
private E unlinkLast(Node<E> l) {
    // assert l == last && l != null;
    final E element = l.item;
    final Node<E> prev = l.prev;
    l.item = null;
    l.prev = null; // help GC
    last = prev;
    if (prev == null)
        first = null;
    else
        prev.next = null;
    size--;
    modCount++;
    return element;
}
删除首次出现:removeFirstOccurrence(Object o)
public boolean removeFirstOccurrence(Object o) {
    // 调用删除方法
    return remove(o);
}

Map

HashMap

属性
// ====================默认配置===================================    
    /**
     * 默认的初始化长度,必须为2的幂次方
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    /**
     * 最大长度 ,最大为2的30次幂
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * 默认的负载因子
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 链表转换为红黑树的条件值
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2 and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * 红黑树转换为链表的条件值
     * The bin count threshold for untreeifying a (split) bin during a
     * resize operation. Should be less than TREEIFY_THRESHOLD, and at
     * most 6 to mesh with shrinkage detection under removal.
     */
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * 链表转换为红黑树时,数组的最小容量
     * 若数组长度小于这个值时,不会存在树化的操作
     * The smallest table capacity for which bins may be treeified.
     * (Otherwise the table is resized if too many nodes in a bin.)
     * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
     * between resizing and treeification thresholds.
     */
    static final int MIN_TREEIFY_CAPACITY = 64;

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

    /**
     * 数组,初次使用时初始化,长度始终是2的幂次方
     * The table, initialized on first use, and resized as
     * necessary. When allocated, length is always a power of two.
     * (We also tolerate length zero in some operations to allow
     * bootstrapping mechanics that are currently not needed.)
     */
    transient Node<K,V>[] table;

    /**
     * 键值对的集合
     * Holds cached entrySet(). Note that AbstractMap fields are used
     * for keySet() and values().
     */
    transient Set<Map.Entry<K,V>> entrySet;

    /**
     * map中key-value键值对的数量
     * The number of key-value mappings contained in this map.
     */
    transient int size;

    /**
     * 集合修改次数
     * The number of times this HashMap has been structurally modified
     * Structural modifications are those that change the number of mappings in
     * the HashMap or otherwise modify its internal structure (e.g.,
     * rehash).  This field is used to make iterators on Collection-views of
     * the HashMap fail-fast.  (See ConcurrentModificationException).
     */
    transient int modCount;

    /**
     * 下一个要调整的长度值(capacity * load factor)
     * The next size value at which to resize (capacity * load factor).
     *
     * @serial
     */
    // (The javadoc description is true upon serialization.
    // Additionally, if the table array has not been allocated, this
    // field holds the initial array capacity, or zero signifying
    // DEFAULT_INITIAL_CAPACITY.)
    int threshold;

    /**
     * 表的负载因子
     * The load factor for the hash table.
     *
     * @serial
     */
    final float loadFactor;

定义的数据结构
Node
static class Node<K,V> implements Map.Entry<K,V> {
    // 节点的hash值
    final int hash;
    // 键值对中的key值
    final K key;
    // 键值对中的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;
    }
    //...包含get、set、hashCode和toString方法
}
TreeNode
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);
    }
    
    // ... 节点中方法
}

// LinkedHashMap.Entry 
 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);
     }
 }
初始化
// 空参构造,指定默认的负载因子
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
// 指定初始化长度的构造方法
public HashMap(int initialCapacity) {
     this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

/**
 * 指定初始化长度和负载因子的构造方法
 * 
 * @param initialCapacity  初始化长度
 * @param loadFactor       负载因子
 */
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);
}

// 参数为集合的构造方法
// 默认负载因子
public HashMap(Map<? extends K, ? extends V> m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}

/**
 * Implements Map.putAll and Map constructor.
 * 在putAll中和构造方法中调用
 * 
 * @param m the map
 * @param evict false when initially constructing this map, else
 * true (relayed to method afterNodeInsertion). 
 * false为初始化调用, true为非初始化调用
 */
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
    int s = m.size();
    if (s > 0) {
        // 集合为空时
        if (table == null) { // pre-size
            // 计算当前需要的map集合长度
            // HashMap底层的table在entry_count>table_size*load_factory时会扩容。
		   // 为了不让HashMap扩容,需要table_size >= entry_count / load_factor。
		   // 公式((float)s / loadFactor) + 1.0F中的size是使用float计算的,+1.0F是因为((float)s / loadFactor)使用float计算,在转换成整数的时候会进行舍入
            // 为了保证最终计算出来的size足够大不至于触发扩容,所以进行了+ 1.0F操作
        
            float ft = ((float)s / loadFactor) + 1.0F;
            // 所需长度与最大长度比较
            int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft : MAXIMUM_CAPACITY);
            if (t > threshold)
                // 扰动函数,重新计算扩容需要的长度
                threshold = tableSizeFor(t);
        }
        else if (s > threshold)
            // 扩容操作
            resize();
        // 遍历待插入的集合,将元素保存到新的集合中
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            putVal(hash(key), key, value, false, evict);
        }
    }
}
put方法
// 保存元素
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
putVal方法
/**
 * 
 * @param hash 集合map中key的hash值
 * @param key 键值对中的key值
 * @param value 键值对中的value值
 * @param onlyIfAbsent (true/false) 当为true时,不修改当前值
 * @param evict false为初始化调用, true为非初始化调用
 */
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
    // tab 数组对象、p 数组中的数据节点、n 数组长度、i 数组中的下标
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    if ((tab = table) == null || (n = tab.length) == 0)
        // 数组为空或者长度为0,则初始化数组
        n = (tab = resize()).length;
    // 判断新增的key在对应位置是否有数据
    // 是否发生hash冲撞
    if ((p = tab[i = (n - 1) & hash]) == null)
        // 将新添加的元素存放到数组中
        tab[i] = newNode(hash, key, value, null);
    else {
        // 发生hash冲撞
        // p是原数据节点
        Node<K,V> e; K k;
        // p.hash == hash 原数据节点的hash值与新存入节点的hash值相同
        // (k = p.key) == key 原数据节点的key值与新存入节点的key地址值相同
        // (key != null && key.equals(k)) 新存入节点不为null,并且与原节点的值相同
        if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
            // 新存入的节点的key在map中存在,取出已存在的节点p
            e = p;
        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;
                }
                // 探地址法搜寻的节点是否与当前节点的key值相同,相同则跳出循环
                if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                // 指针后移操作
                p = e;
            }
        }
        // map中已存在的节点不为空
        if (e != null) { // existing mapping for key
            V oldValue = e.value;
            // 是否更新值,若onlyIfAbsent为false或者已存在节点的值为空,更新当前key对应的值
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    // 修改被修改次数
    ++modCount;
    // 判断当前长度是否需要扩容
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}
扩容:resize()
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 
        // 校验新的长度是否达到最大长度
        // 原始长度是否大于等于默认初始化长度(16)
        else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                 oldCap >= DEFAULT_INITIAL_CAPACITY)
            // 扩容后的阈值 = 原始阈值 * 2
            newThr = oldThr << 1; // double threshold
    }
    else if (oldThr > 0) // initial capacity was placed in threshold
        // 原数组长度为0,扩容阈值大于0时,将阈值赋值给节点数组的初始化长度
        newCap = oldThr;
    else {               // zero initial threshold signifies using defaults
        // map的无参构造,首次初始化
        newCap = DEFAULT_INITIAL_CAPACITY;
        newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
    }
    // 新的阈值为0,则进行阈值的重新计算
    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<K,V> e;
            if ((e = oldTab[j]) != null) {
                // 取出原始数组中的数据,并将原始数组对应索引位置的数据置为null
                oldTab[j] = null;
                if (e.next == null)
                    // 当前节点是单独的节点,指向下一个节点的指针为null
                    // 重新计算hash值,存放到新的节点数组中
                    newTab[e.hash & (newCap - 1)] = e;
                else if (e instanceof TreeNode)
                    // 取树节点
                    ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                else { // preserve order
                    // 节点的hash值与原始长度做&运算,等于0则位于低位,不等于0则处于高位
                    // 将新的数组,按照原始长度分为两部分,大于的设为高位区,小于设为低位区
                    // 将原始数组中的链表重新计算,低位则存在低位区,高位则存在高位区
                    // 低位链表头结点,低位链表尾节点
                    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 split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) {
    TreeNode<K,V> b = this;
    // Relink into lo and hi lists, preserving order
    // 低位节点
    TreeNode<K,V> loHead = null, loTail = null;
    // 高位节点
    TreeNode<K,V> hiHead = null, hiTail = null;
    int lc = 0, hc = 0;
    // 遍历树节点,将原树形节点结构,转换成链表结构
    for (TreeNode<K,V> e = b, next; e != null; e = next) {
        next = (TreeNode<K,V>)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)
            // TreeNode类型节点链表转换成Node类型节点链表
            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)
            // TreeNode类型节点链表转换成Node类型节点链表
            tab[index + bit] = hiHead.untreeify(map);
        else {
            // 链表树化操作
            tab[index + bit] = hiHead;
            if (loHead != null)
                hiHead.treeify(tab);
        }
    }
}
新增树节点:putTreeVal
/**
 * 
 * @param map 集合对象
 * @param tab 节点数组对象
 * @param h   key的hash值
 * @param k   键值对的key
 * @param v   键值对的value
 */
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;
        // 新存入节点hash值与当前树节点hash值比较
        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 
            // 校验键值对中key的类型是否为null:(kc == null && (kc = comparableClassFor(k)) == null)
            // kc 为k的类型
            if ((kc == null && (kc = comparableClassFor(k)) == null)
                // 比较pk的类型与k的类型,再比较k与pk的值
                ||  (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;
            }
            // 判断新增的key是在左子树还是右子树
            dir = tieBreakOrder(k, pk);
        }

        TreeNode<K,V> xp = p;
        // 根据dir判断遍历左子树还是右子树
        if ((p = (dir <= 0) ? p.left : p.right) == null) {
            // 当前 p 节点是叶子节点
            Node<K,V> xpn = xp.next;
            TreeNode<K,V> 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;
            // 新增节点保存到tab中,平衡插入树节点
            moveRootToFront(tab, balanceInsertion(root, x));
            return null;
        }
    }
}

// 获取根节点
final TreeNode<K,V> root() {
    for (TreeNode<K,V> r = this, p;;) {
        if ((p = r.parent) == null)
            return r;
        r = p;
    }
}
// 比较k与x的值
// 若x为null或者x类型与k的类型不同,则返回0;否则返回k与x的比较的值
 static int compareComparables(Class<?> kc, Object k, Object x) {
     return (x == null || x.getClass() != kc ? 0 : ((Comparable)k).compareTo(x));
 }
链表树化:treeifyBin
final void treeifyBin(Node<K,V>[] tab, int hash) {
    int n, index; Node<K,V> e;
    // 节点数组为null,节点数组长度小于64;进行扩容操作
    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
        resize();
    // 获取节点数组中的node节点e
    else if ((e = tab[index = (n - 1) & hash]) != null) {
        // hd 树的首节点
        TreeNode<K,V> hd = null, tl = null;
        // 循环遍历链表,将链表转换成树节点
        // 此时的hd并不是树,此时还是链表,只是链表中每个节点类型都为TreeNode类型
        do {
            // 将链表e节点转换成树p节点
            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);
    }
}

TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
    return new TreeNode<>(p.hash, p.key, p.value, next);
}
// 转化成红黑树
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);
}
remove方法
根据key删除:remove(Object key)
public V remove(Object key) {
    Node<K,V> e;
    return (e = removeNode(hash(key), key, null, false, true)) == null ?
        null : e.value;
}
删除指定键值对:remove(Object key, Object value)
public boolean remove(Object key, Object value) {
    return removeNode(hash(key), key, value, true, true) != null;
}

removeNode(int hash, Object key, Object value,boolean matchValue, boolean movable)

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;
    // 节点数组存在,对应key的值不为null
    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;
        // 获取到待删除的节点node的信息
        if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
            node = p;
        else if ((e = p.next) != null) {
            if (p instanceof TreeNode)
                node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
            else {
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k)))) {
                        node = e;
                        break;
                    }
                    p = e;
                } while ((e = e.next) != null);
            }
        }
        // 执行节点的删除操作
        if (node != null && (!matchValue || (v = node.value) == value || (value != null && value.equals(v)))) {
            if (node instanceof TreeNode)
                ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
            else if (node == p)
                tab[index] = node.next;
            else
                p.next = node.next;
            ++modCount;
            --size;
            afterNodeRemoval(node);
            return node;
        }
    }
    return null;
}

removeTreeNode方法

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();
    // 根节点为null
    // movable为true 并且(根节点的右节点为空或者左节点为空或者左节点的左节点为空)
    if (root == null
        || (movable && (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);
}
扰动函数:tableSizeFor
// 计算出大于当前值的最小2的幂次方的值
// 图解:扰动函数.png
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;
}

LinkedHashMap

属性
// 双向链表头结点
transient LinkedHashMap.Entry<K,V> head;

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

// 此链接的哈希映射的迭代排序方法:
//  true 用于访问顺序,
//  false 用于插入顺序。
final boolean accessOrder;
定义的数据结构
Entry
// 自定义结构类型,继承了HashM中的Node类型
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);
    }
}
初始化
// 无参构造
public LinkedHashMap() {
    super();
    accessOrder = false;
}
// 初始化长度
public LinkedHashMap(int initialCapacity) {
    super(initialCapacity);
    accessOrder = false;
}
// 初始化长度和负载因子
public LinkedHashMap(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor);
    accessOrder = false;
}
// 初始化长度、负载因子和迭代排序的类型
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}
// 参数为集合的初始化方法
public LinkedHashMap(Map<? extends K, ? extends V> m) {
    super();
    accessOrder = false;
    putMapEntries(m, false);
}
put方法 和 remove方法

同HashMap的put方法和remove(Object key)方法

// 继承了HashMap的put方法和remove(Object key)方法,
// 重写了newNode方法、
// newTreeNode方法、
// afterNodeAccess方法、
// afterNodeInsertion方法、
// afterNodeRemoval方法、
// replacementTreeNode方法
newNode 和 newTreeNode
// 创建节点
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;
}
// putTreeVal中的newTreeNode方法
TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {
     TreeNode<K,V> p = new TreeNode<K,V>(hash, key, value, next);
     linkNodeLast(p);
     return p;
 }

// 将新节点保存到双向链表中
 private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
     LinkedHashMap.Entry<K,V> last = tail;
     tail = p;
     if (last == null)
         head = p;
     else {
         p.before = last;
         last.after = p;
     }
 }
afterNodeAccess
// 将当前节点移到链表尾部
void afterNodeAccess(Node<K,V> e) { // move node to last
    LinkedHashMap.Entry<K,V> last;
    if (accessOrder && (last = tail) != e) {
        LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
        p.after = null;
        if (b == null)
            head = a;
        else
            b.after = a;
        if (a != null)
            a.before = b;
        else
            last = b;
        if (last == null)
            head = p;
        else {
            p.before = last;
            last.after = p;
        }
        tail = p;
        ++modCount;
    }
}
afterNodeInsertion
// 删除头结点
// 此处应为扩展操作
 void afterNodeInsertion(boolean evict) { // possibly remove eldest
     LinkedHashMap.Entry<K,V> first;
     // evict 为false是初始化时候调用;true时为新增时调用
     // 判断是否要删除头结点
     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;
}
afterNodeRemoval
// 删除双向链表中的节点
// 删除额外维护的链表中的已经删除的节点
void afterNodeRemoval(Node<K,V> e) { // unlink
    LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
    p.before = p.after = null;
    if (b == null)
        head = a;
    else
        b.after = a;
    if (a == null)
        tail = b;
    else
        a.before = b;
}
replacementTreeNode
// 替换为树节点
TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
    LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
    TreeNode<K,V> t = new TreeNode<K,V>(q.hash, q.key, q.value, next);
    transferLinks(q, t);
    return t;
}
// 用dst节点替换src节点
private void transferLinks(LinkedHashMap.Entry<K,V> src, LinkedHashMap.Entry<K,V> dst) {
    LinkedHashMap.Entry<K,V> b = dst.before = src.before;
    LinkedHashMap.Entry<K,V> a = dst.after = src.after;
    if (b == null)
        head = dst;
    else
        b.after = dst;
    if (a == null)
        tail = dst;
    else
        a.before = dst;
}
遍历

LinkedHashMap中额外维护了一个双向链表,在遍历的时候,可以有序的取出存入的元素数据。

Set

HashSet

属性
// set集合保存数据的结构类型
private transient HashMap<E,Object> map;
// map对象中key-value中的value值
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

初始化
// 无参构造
public HashSet() {
    map = new HashMap<>();
}
// 指定初始化长度
public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}
// 指定初始化长度和负载因子
public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
}
// 指定初始化长度和负载因子和布尔值,为了区分HashSet(int initialCapacity, float loadFactor)构造方法
// (This package private constructor is only used by LinkedHashSet.)
// 依次方法创建一个LinkedHashMap对象,保证有序性
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
// 参数为集合的构造方法
public HashSet(Collection<? extends E> c) {
    // 根据集合的长度,确定初始化的最大长度
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    // 集合保存到map中
    addAll(c);
}

add方法
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}
remove方法
public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
}

LinkedHashSet

初始化
// 继承了HashSet,通过调用父类中 HashSet(int initialCapacity, float loadFactor, boolean dummy) 初始化方法,
// 创建一个LinkedHashMap对象,保证有序性的实现
public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);
}

public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);
}

public LinkedHashSet() {
    super(16, .75f, true);
}


public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);
    addAll(c);
}