底層由TreeMap實現html
基於紅黑樹實現,支持有序性操做,例如根據一個範圍查找元素的操做。可是查找效率不如 HashSet,HashSet 查找的時間複雜度爲 O(1),TreeSet 則爲 O(logN)。java
基於哈希表實現,支持快速查找,但不支持有序性操做。而且失去了元素的插入順序信息【由HashMap的數據存儲行爲有關係】,也就是說使用 Iterator 遍歷 HashSet 獲得的結果是不肯定的。node
數據實現由hashmap實現, Key就是輸入的變量。value是一個統一的Object數據算法
具備 HashSet 的查找效率,且內部使用雙向鏈表維護元素的插入順序。【本質是不斷的經過hash值計算來進行下一個數值的查找】設計模式
ArrayList:基於動態數組實現,支持隨機訪問【查找複雜度O(1),本質是一個數組】。數組
Vector:和 ArrayList 相似,但它是線程安全的【區別sychronized修飾,作了同步處理】。緩存
LinkedList:基於雙向鏈表實現,只能順序訪問,可是能夠快速地在鏈表中間插入和刪除元素。【普通for遍歷每次都要重頭開始,Iterator方法是有一個光標指向這裏】不只如此,LinkedList 還能夠用做棧【LIFO】、隊列和【FIFO,能夠用來作生產者消費者設計模式】雙向隊列【集合前兩種的功能】。http://www.javashuo.com/article/p-vewneihc-hk.html安全
一個基於優先級的無界優先級隊列。優先級隊列的元素按照其天然順序進行排序,或者根據構造隊列時提供的 Comparator 進行排序,具體取決於所使用的構造方法。該隊列不容許使用 null 元素也不容許插入不可比較的對象(沒有實現Comparable接口的對象)。數據結構
Java中PriorityQueue經過二叉小頂堆實現,能夠用一棵徹底二叉樹表示(任意一個非葉子節點的權值,都不大於其左右子節點的權值)多線程
public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {
1>PriorityQueue是一種無界的,線程不安全的隊列
2>PriorityQueue是一種經過數組實現的,並擁有優先級的隊列
3>PriorityQueue存儲的元素要求必須是可比較的對象, 若是不是就必須明確指定比較器【能夠插入相同數據】
須要理解堆這個數據結構就很好辦了
leftNo = parentNo*2+1
rightNo = parentNo*2+2
parentNo = (nodeNo-1)/2
基於紅黑樹實現。
基於哈希表實現【這個詳見Java-HashMap實現原理】
和 HashMap 相似,但它是線程安全的,這意味着同一時刻多個線程能夠同時寫入 HashTable 而且不會致使數據不一致。
它是遺留類,不該該去使用它。如今可使用 ConcurrentHashMap 來支持線程安全,而且 ConcurrentHashMap 的效率會更高,由於 ConcurrentHashMap 引入了分段鎖。
相似於:HashTable中的鎖相似於MySQL中的表級鎖Segments所有鎖定、ConcurrentHashMap 相似於MySQL中的行級鎖單個Segment鎖定
HashTable容器在競爭激烈的併發環境下表現出效率低下的緣由,是由於全部訪問HashTable的線程都必須競爭同一把鎖,那假如容器裏有多把鎖,每一把鎖用於鎖容器其中一部分數據,那麼當多線程訪問容器裏不一樣數據段的數據時,線程間就不會存在鎖競爭,從而能夠有效的提升併發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術,首先將數據分紅一段一段的存儲,而後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其餘段的數據也能被其餘線程訪問。有些方法須要跨段,好比size()和containsValue(),它們可能須要鎖定整個表而而不只僅是某個段,這須要按順序鎖定全部段,操做完畢後,又按順序釋放全部段的鎖。這裏「按順序」是很重要的,不然極有可能出現死鎖,在ConcurrentHashMap內部,段數組是final的,而且其成員變量實際上也是final的,可是,僅僅是將數組聲明爲final的並不保證數組成員也是final的,這須要實現上的保證。這能夠確保不會出現死鎖,由於得到鎖的順序是固定的。
特點之處:
①能夠看到ConcurrentHashMap會首先使用Wang/Jenkins hash的變種算法對元素的hashCode進行一次再哈希
② (hash >>> segmentShift) & segmentMask//向右無符號移動28位,意思是讓高4位參與到hash運算中,
③Segment小鎖鎖定數據各個數據默認16個,讀
④執行 size 操做時,先不加鎖兩次結果相同,就直接使用使用這個結果;不然對每個Segment加鎖統計各個count和;
JDK 1.7 使用分段鎖機制來實現併發更新操做,核心類爲 Segment,它繼承自重入鎖 ReentrantLock,併發度與 Segment 數量相等。
JDK 1.8 使用了 CAS 操做來支持更高的併發度,在 CAS 操做失敗時使用內置鎖 synchronized。
而且 JDK 1.8 的實現也在鏈表過長時會轉換爲紅黑樹。
使用雙向鏈表來維護元素的順序,順序爲插入順序或者最近最少使用(LRU)順序。 https://www.jianshu.com/p/8f4f58b4b8ab
而後把accessOrder【LinkedHashMap特有的】設置爲false,這就跟存儲的順序有關了,LinkedHashMap存儲數據是有序的,並且分爲兩種:插入順序【head-tail】和訪問順序【0-(size-1)遍歷順序】。
accessOrder設置爲false,表示不是訪問順序而是插入順序存儲的,這也是默認值,表示LinkedHashMap中存儲的順序是按照調用put方法插入的順序進行排序的
header是一個Entry類型的雙向鏈表表頭,自己不存儲數據。
插入尾部、清楚頭部
Least Recently Used
package com.cnblogs.mufasa.Map; import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends LinkedHashMap<K, V> { private int maxEntries;//設置的cache數據大小 public LRUCache(int maxEntries) { super(16, 0.75f, true); this.maxEntries = maxEntries; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { //插入新數據的時候判斷是否超額 //是,清楚head-next數據,插入新數據在head-pre //否,插入head-pre就行 return size() > maxEntries; } }
package com.cnblogs.mufasa.Map; import org.w3c.dom.Node; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; public class Client { public static void main(String[] args) { // HashMap<Integer,String> hm=new HashMap<>(); // ConcurrentHashMap<Integer,String> chm=new ConcurrentHashMap<>(); //TreeMap // TreeMap<Integer,String> map =new TreeMap<>(); // map.put(3, "val"); // map.put(2, "val"); // map.put(1, "val"); // map.put(5, "val"); // map.put(4, "val"); // System.out.println(map); // Integer integer=new Integer(1); // System.out.println(Integer.parseInt("111",2)); // System.out.println(8^111); // String a1="hello"; // String a2=new String("hello"); // System.out.println(a1==a2); // LRUCache<String,Object> cache = new LRUCache<>(3); cache.put("a","abstract"); cache.put("b","basic"); cache.put("c","call"); cache.put("e","hello"); cache.put("d",null); cache.put(null,"null"); cache.get("e"); cache.put("f","滴滴滴"); System.out.println(cache); // 輸出爲:{c=call, a=abstract, d=滴滴滴} } } /* {null=null, e=hello, f=滴滴滴} */
WeakHashMap 的 Entry 繼承自 WeakReference,被 WeakReference 關聯的對象在下一次垃圾回收時會被回收。
WeakHashMap 主要用來實現緩存,經過使用 WeakHashMap 來引用緩存對象,由 JVM 對這部分緩存進行回收。
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>
Tomcat 中的 ConcurrentCache 使用了 WeakHashMap 來實現緩存功能。
ConcurrentCache 採起的是分代緩存:
核心源碼:
public final class ConcurrentCache<K, V> { private final int size; private final Map<K, V> eden; private final Map<K, V> longterm; public ConcurrentCache(int size) { this.size = size; this.eden = new ConcurrentHashMap<>(size); this.longterm = new WeakHashMap<>(size); } public V get(K k) { V v = this.eden.get(k); if (v == null) { v = this.longterm.get(k); if (v != null) this.eden.put(k, v); } return v; } public void put(K k, V v) { if (this.eden.size() >= size) { this.longterm.putAll(this.eden); this.eden.clear(); } this.eden.put(k, v); } }
java.util.Arrays#asList() 能夠把數組類型轉換爲 List 類型。
A-適配器-B
@SafeVarargs public static <T> List<T> asList(T... a)
讓用戶經過特定的接口訪問容器的數據,不須要了解容器內部的數據結構
LinkedList<String> list = new LinkedList<>(); list.add("a"); list.add("b"); // for (String item : list) { // System.out.println(item); // } Iterator<String> iterator=list.iterator(); Iterator<String> iterator2=list.descendingIterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
Queue隊列能夠直接當作這個模式的數據結構