原創不易,如需轉載,請註明出處http://www.javashuo.com/article/p-sgixxweu-bx.html,不然將追究法律責任!!! html
底層實現,源碼以下:java
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID = -5024744406713321676L; //賣個關子,這裏爲啥要用transient關鍵字? 評論區見哦! private transient HashMap<E,Object> map; private static final Object PRESENT = new Object(); public HashSet() { map = new HashMap<>(); } public boolean add(E e) { return map.put(e, PRESENT)==null; } ... }
不用多說,是不沒想到,原來HashSet是基於HashMap實現的,元素都存到HashMap鍵值對的Key上面,而Value時有一個統一的值private static final Object PRESENT = new Object();git
底層實現,源碼以下:github
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable { private transient NavigableMap<E,Object> m; private static final Object PRESENT = new Object(); TreeSet(NavigableMap<E,Object> m) { this.m = m; } public TreeSet() { this(new TreeMap<E,Object>()); } public boolean add(E e) { return m.put(e, PRESENT)==null; } }我去,又是這個尿性,基於TreeMap來實現的
底層實現,源碼以下:算法
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; 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); } }都是super,實現了把HashSet中預留的構造方法啓用了,於是能夠實現有序插入(LinkedHashMap再談究竟)
Jdk1.7數據存儲結構(採用數組+鏈表)segmentfault
Jdk1.8數據存儲結構(採用數組+鏈表+紅黑樹)數組
注意:在鏈表長度大於8後,查詢複雜度由O(n)變爲O(logn),將鏈表存儲轉換成紅黑樹存儲(也就是TreeMap)安全
紅黑樹R-B Tree簡介(本質實際上是2-3-4樹):數據結構
二叉樹特性: (1)左字數上全部的節點的值都小於或等於他的根節點上的值 (2)右子樹上全部節點的值均大於或等於他的根節點的值 (3)左、右子樹也分別爲二叉樹 紅黑樹特色(一種平衡二叉樹): (1)每一個結點要麼是紅的要麼是黑的。 (2)根結點是黑的。 (3)每一個葉結點(葉結點即指樹尾端NIL指針或NULL結點)都是黑的。 (4)若是一個結點是紅的,那麼它的兩個兒子都是黑的。 (5)對於任意結點而言,其到葉結點樹尾端NIL指針的每條路徑都包含相同數目的黑結點 節點操做: (1)左旋 (2)右旋 (3)變色
底層實現,源碼以下:併發
static class Entry<K,V> extends HashMap.Node<K,V> { //這裏維護了一個before和after的Entry, 見名思意, 就是每一個Entry<K,V>都維護它的上一個元素和下一個元素的關係。這也是LinkedHashMap有序的關鍵所在。 Entry<K,V> before, after; Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } }
LinkedHashMap是繼承HashMap, 也就是說LinkedHashMap的結構也是和HashMap那樣(數組+鏈表)
注意:LinkedHashMap分爲插入的順序排列和訪問的順序排列兩種方式,經過accessOrder參數來控制
我的博客地址:
csdn:https://blog.csdn.net/tiantuo6513
cnblogs:https://www.cnblogs.com/baixianlong
segmentfault:https://segmentfault.com/u/baixianlong
github:https://github.com/xianlongbai