Java主要容器

总结容器中重要使用的数据结构。

先罗列接口和抽象类(主要的)的组织结构:

接口:
-Collection
--List
--Set
---SortedSet
----NavigableSet
--Queue
---Deque

-Map
--SortedMap
---NavigableMap
抽象类:
-AbstractCollection
--AbstractList
---AbstractSequentialList
----LinkedList(1.掌握)
---ArrayList(2.掌握)
---Vector(3.掌握)
----Stack(4.掌握)
--AbstractSet
---HashSet(5.掌握)
---TreeSet(6.掌握)
--ArrayDeque(7.掌握)

-AbstractMap
--HashMap(8.掌握)
--TreeMap(9.掌握)
--IdentityHashMap(10.熟悉)
--WeakHashMap(11.熟悉)

-Hashtable(12.掌握)
-LinkedHashMap(13.掌握)
1.LinkedList
public class LinkedList<E> 
		extends AbstractSequentialList<E>
		implements List<E>, Deque<E>, Cloneable, Serializable

基本结构:
	Node<E> first;//头指针
	Node<E> last;//尾指针

结构特点:
	1.双向链表
	2.not synchronized(非同步)

思想:
	采用双向链表的方式进行数据存储。每个结点含有三个域:一个数据域,两个指针域(prev,next)。

优点:
	1.在内存无限制的环境下,数据存储量不限。
	2.在数据的插入、删除操作上简单。只需要改变prev和next的指向对象。
	3.数据的写入顺序和逻辑存储顺序一致
缺点:
	1.每查找特点的元素,需要遍历整个链表。最坏的时间复杂度为o(n)

2.ArrayList
public class ArrayList<E>
		extends AbstractList<E>
		implements List<E>, RandomAccess, Cloneable, Serializable

基本结构:
	transient Object[] elementData;//数组
	private static final int DEFAULT_CAPACITY = 10;//默认存储大小
	private int size;//记录数据

结构特点:
	1.动态数组
	2.not synchronized(非同步)
	
思想:
	采用动态数组对数据进行存储,设置数组默认大小,超过容量扩容,每次扩容大小为原始容量的0.5倍。数组最大
	容量为Integer.MAX_VALUE。
	
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
}	

优点:
	1.利用数组的优点,随机读取速度快。时间复杂度O(1)。
	2.数据的写入顺序和逻辑存储顺序一致
缺点:
	1.插入和删除改变了数组的结构,数组中其他元素需要移位。时间开销最坏为o(n)
	2.数组容量有限,数组过大时,扩容开销也大。
	
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));//扩容的核心:数组的拷贝
        return copy;
}

3.Vector
public class Vector<E>
		extends AbstractList<E>
		implements List<E>, RandomAccess, Cloneable, Serializable

基本结构:
	protected Object[] elementData;//数组
	protected int elementCount;//计数
	protected int capacityIncrement;//数组增量
	
结构特点:
	1.动态数组
	2.synchronized(同步)

优点:1.同ArrayList
	2.线程安全

缺点:1.同ArrayList
	2.在不需要线程安全的情况下,使用Vector效率低于ArrayList

不同于ArrayList之处:
	1.Vector同步,ArrayList不同步
	2.Vector自定义数组扩容大小,ArrayList系统默认。
	
	 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //不指定capacityIncrement时,扩容一倍;指定capacityIncrement,按capacityIncrement扩容
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

4.Stack
public class Stack<E>
		extends Vector<E>

基本结构:
	protected Object[] elementData;//数组
	protected int elementCount;//计数

结构特点:
	1.栈
	2.synchronized(同步)
	2.动态数组

优点:1.先进后出
	2.线程安全
	3.争议:Stack实现了Vector,可以调用父类的方法,不但可以对栈顶元素进行操作,还可以进行随机
	元素的增删查改。

缺点:1.容量有限

5.HashSet
public class HashSet<E>
	extends AbstractSet<E>
	implements Set<E>, Cloneable, Serializable

基本结构:
	private transient HashMap<E,Object> map;
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

结构特点:
	1.动态数组+单向链表+红黑树
	2.not synchronized(非同步)
	3.散列表

思想:
	1.利用HashMap 的键的唯一性,构建“集”。
	2.集通过数据的hashcode值进行映射地址。
	3.采用单向链表对同一地址的数据进行存储

hash映射方法:
	见HashMap

优点:1.读取、插入、删除速度时间短

缺点:1.存储地址根据hash映射,无法顺序存储


6.TreeSet
public class TreeSet<E>
		extends AbstractSet<E>
		implements NavigableSet<E>, Cloneable, Serializable
基本结构:
	private transient NavigableMap<E,Object> m;//TreeMap
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

结构特点:
	1.红黑树
	2.not synchronized(非同步)
  
思想:
	1.利用红黑树的二分查找思想,对数据进行顺序存储

注意:存储的元素类必须实现Comparable接口 或者 在构造方法中给出Comparator并实现compare方法

优点:1.顺序存储

缺点:1.相比HashSet类,TreeSet类插入元素和删除元素速度较慢。因为需要重新对红黑数进行平衡。

7.ArrayDeque
public class ArrayDeque<E>
		extends AbstractCollection<E>
		implements Deque<E>, Cloneable, Serializable

基本结构:
	transient Object[] elements; // non-private to simplify nested class access

    /**
     * The index of the element at the head of the deque (which is the
     * element that would be removed by remove() or pop()); or an
     * arbitrary number equal to tail if the deque is empty.
     */
    transient int head;

    /**
     * The index at which the next element would be added to the tail
     * of the deque (via addLast(E), add(E), or push(E)).
     */
    transient int tail;

结构特点:
	1.动态数组
	2.栈
	3.队列
	4.双向队列
	5.循环队列
思想:
	对数组指定一个头指针和尾指针。即可以头插头删,也可以尾插尾删。不可以对非头尾结点进行查找。

	栈:数组进行尾插尾删
	循环队列:头删尾入。当头遇到尾时,数组扩容。
	
	private static final int MIN_INITIAL_CAPACITY = 8;//默认数组大小
	
	private void doubleCapacity() {//数组扩容1倍
        assert head == tail;
        int p = head;
        int n = elements.length;
        int r = n - p; // number of elements to the right of p
        int newCapacity = n << 1;
        if (newCapacity < 0)
            throw new IllegalStateException("Sorry, deque too big");
        Object[] a = new Object[newCapacity];
        System.arraycopy(elements, p, a, 0, r);
        System.arraycopy(elements, 0, a, r, p);
        elements = a;
        head = 0;
        tail = n;
    }
    
    public void addFirst(E e) {//头插
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;//循环数组
        if (head == tail)//头遇到尾
            doubleCapacity();//扩容
    }
    
    public void addLast(E e) {//尾插
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)//循环数组
            doubleCapacity();//扩容
    }

优点:1.实现栈和队列两个数据结构
	2.循环数组利用空间

缺点:1.not synchronized(非同步)

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

基本结构:
	transient Node<K,V>[] table;//数组
	static class Node<K,V> implements Map.Entry<K,V>;//单向链表
	static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> ;//红黑树
	static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//默认数组容量
	static final int MAXIMUM_CAPACITY = 1 << 30;//最大数组容量
	static final float DEFAULT_LOAD_FACTOR = 0.75f;//装填因子
	static final int TREEIFY_THRESHOLD = 8;//树化阈值
	static final int UNTREEIFY_THRESHOLD = 6;//链化阈值
	transient int size;//键值对数
	int threshold;//临界容量
	
结构特点:
	1.动态数组+单向链表+红黑树
	2.键值对映射
	3.散列表

hash映射方法:
	static final int hash(Object key) {
        int h;
        //hashcode值 异或 h >>> 16
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

数组下标地址映射:
	/*
	*hash 为 数的hash映射值,n为数组容量。i为映射下标值
	*/
	tab[i = (n - 1) & hash]

同一hash映射值存储于同一个数组单元中,每个单元默认采用单向链表连接数据。

当链表长度小于 8 时,采用 单向链表 连接
	
	单向链表查找元素速度为o(n)

当链表长度大于 8 时,转换为 红黑树 存储

	红黑树查找元素采用二分查找,速度为log(n)

当 table数组元素 size 大于 threshold 时,进行扩容 和 再散列。

	if (++size > threshold)
            resize();
扩容
	else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                     oldCap >= DEFAULT_INITIAL_CAPACITY)//容量扩充一倍
                newThr = oldThr << 1; // double threshold
    新临界阈值:
    	float ft = (float)newCap * loadFactor;//新容量 * 装填因子
再散列:
	对每个元素进行重新的hash映射地址。
	若新的下标元素集元素低于 UNTREEIFY_THRESHOLD 值 时,红黑树 转为 单向链表

注意:
	jdk1.8之前,HashMap 只采用单向链表来解决哈希冲突。
	jdk1.8及以后,HashMap采用 单向链表+红黑树的方式来综合使用,大大提高了查找的效率。

优点:1.动态数组+链表

缺点:1.not synchronized(非同步)

9.TreeMap
public class TreeMap<K,V>
		extends AbstractMap<K,V>
		implements NavigableMap<K,V>, Cloneable, Serializable

基本结构:
	private final Comparator<? super K> comparator;//比较器接口

    private transient Entry<K,V> root;//根节点

    /**
    * The number of entries in the tree
    */
    private transient int size = 0;//键值对数

    /**
     * The number of structural modifications to the tree.
     */
    private transient int modCount = 0;//修改计数
    
    static final class Entry<K,V> implements Map.Entry<K,V>;//红黑树结构
    
结构特点:
	1.红黑树

思想:利用红黑树对数据的二分排列,实现数据的有序存储

注意:元素必须实现Comparable接口或者提供实现了compare方法的Comparator接口

优点:1.查找,插入,删除速度快

缺点:1.在非要求顺序的情况下,HashMap更快
	2.not synchronized(非同步)

10.IdentityHashMap
public class IdentityHashMap<K,V>
		extends AbstractMap<K,V>
		implements Map<K,V>, Serializable, Cloneable

基本结构:
	private static final int DEFAULT_CAPACITY = 32;
	private static final int MINIMUM_CAPACITY = 4;
	private static final int MAXIMUM_CAPACITY = 1 << 29;
	transient Object[] table;
	transient int modCount;

结构特点:
	1.动态数组+单向链表
	2.散列表

思想:
	private static int hash(Object x, int length) {
        int h = System.identityHashCode(x);//利用System.identityHashCode方法映射hash
        // Multiply by -127, and left-shift to use least bit as part of hash
        return ((h << 1) - (h << 8)) & (length - 1);
    }
    
优点:1.每个不同的对象都对应着不同的地址,即使内容相同

缺点:not synchronized(非同步)

11.WeakHashMap
public class WeakHashMap<K,V>
		extends AbstractMap<K,V>
		implements Map<K,V>

基本结构:
	Entry<K,V>[] table;
	private int threshold;
	private final float loadFactor;
	private final ReferenceQueue<Object> queue = new ReferenceQueue<>();//元素引用队列

结构特点:
	1.动态数组+单向链表
	2.散列表
	3.引用队列

思想:对无其他对象访问的键值对(本数组下标除外),添加到queue中,并结合jvm垃圾回收进行处理。

优点:1.内存友好

缺点:not synchronized(非同步)

12.Hashtable
public class Hashtable<K,V>
		extends Dictionary<K,V>
		implements Map<K,V>, Cloneable, Serializable

属性、结构同HashMap一致

优点:synchronized(同步)

13.LinkedHashMap
public class LinkedHashMap<K,V>
		extends HashMap<K,V>
		implements Map<K,V>

基本结构:
	transient LinkedHashMap.Entry<K,V> head;
	transient LinkedHashMap.Entry<K,V> tail;
	final boolean accessOrder;//元素发生改变,就将该元素移到数组最后
	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);
        }
    }

结构特点:
	1.将 HashMap.Node 的 四个域 变成 六个域,添加了 before 域 和 after 域。用于存储前一个结点和后一个结点,建立顺序关系。
	

优点:1.按数据存入顺序存储
	2.aeecessOrder为true时,常操作的元素总在链表最后,最近不常用的数据总在最前面。