基於數組實現,按照插入順序排序,可重複,線程不安全,默認初始化爲空數組對象,在添加第一個元素時,初始化大小爲10的數組。支持自動擴容,擴展因子爲0.5,即 newCapacity=oldCapacity*1.5,擴容方式是 Arrays.copyOf(elementData, newCapacity);。
算法
基於數組實現,按照插入順序排序,可重複,經過 synchronized 來保證線程安全,默認初始化大小爲10的數組。添加元素時。支持自動擴容,擴展因子爲1,即 newCapacity=oldCapacity*2,擴容方式是 Arrays.copyOf(elementData, newCapacity);。數組
基於雙向鏈表實現,按照插入順序排序,實現了接口 Deque,因此它也是一個雙端隊列。安全
1 // 雙端鏈表結構 2 private static class Node<E> { 3 E item; Node<E> next; Node<E> prev; 4 }
基於散列鏈表+紅黑樹實現,無序,鏈表長度>=8時轉爲紅黑樹,紅黑樹<=6時轉爲鏈表,首次添加元素時,初始化默認數組長度16,而且必須是2的冪次方大小,當指定的大小不夠2的冪次方時自動補齊大小,默認加載因子0.75,默認擴展因子1,線程不安全。併發
1 // 哈希鏈表結構 2 static class Node<K,V> implements Map.Entry<K,V> { 3 final int hash; // 數組索引 4 final K key; 5 V value; 6 Node<K,V> next; // 下一個節點 7 } 8 // 紅黑樹結構 9 static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> { 10 TreeNode<K,V> parent; 11 TreeNode<K,V> left; 12 TreeNode<K,V> right; 13 TreeNode<K,V> prev; 14 boolean red; 15 }
添加元素時爲了更均勻地分佈,對 key 進行兩次的 hash 運算。ide
1 static final int hash(Object key) { 2 int h; 3 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 4 }
擴容方式:resize(),擴容後的容量是以前的2倍。spa
1 Node<K,V> loHead = null, loTail = null; 2 Node<K,V> hiHead = null, hiTail = null; 3 Node<K,V> next; 4 do { 5 next = e.next; 6 if ((e.hash & oldCap) == 0) { // 索引沒有變化 7 if (loTail == null) 8 loHead = e; 9 else 10 loTail.next = e; 11 loTail = e; 12 } 13 else { // 索引變爲原索引+oldCap 14 if (hiTail == null) 15 hiHead = e; 16 else 17 hiTail.next = e; 18 hiTail = e; 19 } 20 } while ((e = next) != null); 21 if (loTail != null) { 22 loTail.next = null; 23 newTab[j] = loHead; 24 } 25 if (hiTail != null) { 26 hiTail.next = null; 27 newTab[j + oldCap] = hiHead; 28 }
線程安全性問題線程
一、put 致使數據丟失;code
二、resize 致使的 get 操做時的死循環,JDK 8 已經解決此問題,利用 head 和 tail 來保證鏈表的順序不變,避免致使死循環;對象
基於散列鏈表實現,默認數組長度11,默認加載因子0.75,默認擴展2*原數組長度+1,利用 synchronized 保證線程安全。
blog
基於紅黑樹實現,按 key 天然排序。key 不等於 null。
利用 HashMap 來實現。散列雙向鏈表的結構。
1 static class Entry<K,V> extends HashMap.Node<K,V> { 2 Entry<K,V> before, after; 3 }
accessOrder 的排序方式:
利用 HashMap 實現,無序,去重,默認初始化爲默認的 HashMap,value 固定爲 Object 對象,能夠參考 HashMap 的實現。
1 // 初始化 2 public HashSet() { 3 map = new HashMap<>(); 4 } 5 // 添加元素 6 public boolean add(E e) { 7 return map.put(e, PRESENT)==null; 8 }
利用 TreeMap 實現,天然排序,去重,不能添加 null,默認初始化爲默認的 TreeMap,value 固定爲 Object 對象,能夠參考 TreeMap 的實現。
繼承了 HashSet,利用 LinkedHashMap 實現,能夠參考 LinkedHashMap 的實現。
棧的結構,繼承了 Vector 類,利用 synchronized 來保證線程安全。
隊列 / 雙端隊列的結構,Deque 繼承 Queue 接口。
常見實現: