標籤:
集合OR 容器 通常我們會用數組去儲存一些基礎資料型別 (Elementary Data Type),數組是編譯器支援的類型,但是數組的一個明顯缺點就是具有固定尺寸,而在一般情況下,只有在程式啟動並執行時候,我們才能知道要儲存的具體數目。 Java類庫提供了一套相當完善的容器架構(Collections Framework)來解決這個問題。其中基本的類型是List、Set、Queue和Map。這些物件類型也被稱為集合類,但是由於Java中使用了Collection這個名稱指代該類庫的一個子集,所以一般使用更廣泛的術語“容器”來稱呼它們。 容器的基本任務是儲存對象,更準確的說是儲存對象的引用。但是各種容器的實現是存在很大差異的,沒有一種容器是絕對優秀的能夠適應所有的應用情境,所以我們需要瞭解各種容器的底層實現,然後根據實際的情況選擇合適的容器。從下面的這張容器的分類圖中就能看到Collections Framework的龐大,而且這還不包括Queue介面的實現(PriorityQueue以及各種風格的BlockingQueue等)、ConcurrentMap介面實現、CopyOnWriteArrayList和CopyOnWriteArraySet、EnumSet和EnumMap、以及Collections工具類中的多個工具方法。
Interface介面規範:Collections Framework定義了一些介面規範,那些常用的容器都會繼承某些介面規範,每一種介面都對應給出相應的抽象類別,如果類庫提供的容器不能很好的完成你指定的任務,你可以擴寫這些抽象類別的子類,定製自己的容器。
Collection介面:僅僅表示一組對象的集合,而沒有指定對象的存放次序,以及能否包含重複元素,Collection介面自身還繼承了Iterator介面。 下面要說的很多容器都實現了Collection介面,包括List、Set、Queue、Deque等介面。需要注意的是,同為容器的Map沒有實現Collection介面。 Collection介面定義了容器最基本的一些特性,包含以下的介面方法定義: size方法:返回容器中元素的個數isEmpty方法:返回容器是否為空白contains方法:返回容器中是否包含某個元素iterator方法:返回容器的迭代器add方法:用於向容器中添加元素remove方法:用於刪除容器中的元素clear方法:清空容器中的元素toArray方法:將容器類轉成相應的對象數組
List介面:List繼承於Collection介面,表示一個有序容器,容器內的元素會按照加入的順序有序的存放,允許出現重複的元素,可以基於元素位置的訪問。 List介面在Collection介面的基礎上加上了以下方法的定義, get方法:擷取指定位置的元素set:將指定位置設定成指定的元素indexOf:擷取指定元素在容器中的位置listIterator:返回ListIterator類型的迭代器subList:根據區間位置,擷取容器的子容器
List介面的常見實作類別有ArrayList、LinkedList、Vector等
Set介面:繼承於Collection介面,特點是不能存放相同的元素,對有序性沒有要求,Set介面中的方法定義基本和Collection介面一致,沒有加入新的方法定義。
常見的Set介面的實現有HashSet、SortedSet介面
Queue介面:繼承於Collection介面,是一個被定義用來存放一系列等待進行某個流程元素的容器,除了一些基本的容器操作,Queue隊列還提供了一些額外的插入、提取和檢查的操作。
Queue介面中定義以下的方法: add方法:將指定的元素插入此隊列(如果立即可行且不會違反容量限制),在成功時返回 true,如果當前沒有可用的空間,則拋出 IllegalStateException。offer方法:將指定的元素插入此隊列(如果立即可行且不會違反容量限制),當使用有容量限制的隊列時,此方法通常要優於 add(E),後者可能無法插入元素,而只是拋出一個異常。peek方法:擷取但不移除此隊列的頭;如果此隊列為空白,則返回 null。pool方法:擷取並移除此隊列的頭;如果此隊列為空白,則返回 null。remove方法:擷取並移除此隊列的頭。 包括Deque、BlockingQueue介面都直接繼承與Queue介面
Map介面:是一個關於key(鍵)和value(值)的映射集合,每一個key對應一個value。
Map介面中定義的一些基本方法: size方法:返回容器中元素的個數put方法:向容器中加入元素remove方法:刪除容器中元素isEmpty方法:判斷容器是否為空白contains方法:判斷容器是否包含指定元素clear方法:清除容器中的元素keySet方法:返回Map的key集合,是Set類型的 實現了Map介面的一些類:HashMap、Hashtable、WeakHashMap、SynchronizedMap、ConcurrentMap介面等
Deque介面:繼承於Queue介面,在JDK1.6中被加入,也叫做雙端隊列,即可以在隊列的兩端進行插入和提取操作。 Deque介面在Queue介面的基礎上,加上了addFirst、addLast、offerFirst、offerLast等方法,分別表示這些操作可以在兩端進行。
常見的Deque的實作類別:ArrayDeque、ConcurrentLinkedDeque、LinkedList、BlockingDeque等。
Collections Framework中還包含一些其他的介面,但基本由上述介面擴充而來,如SortedSet、SortedMap、BlockingQueue、BlockingDeque、ConcurrentMap等
______________________________________________________________________________________________________________________________________________________________________
通用的一些實作類別 類庫提供了一些非常有用的基於上述介面的容器實作類別,並且能夠很好的勝任日常開發中的大部分的情境。
HashSet:基於Set介面的Hash表的實現,比較全面的實現了Set介面。元素在容器的中的順序是無序的,底層是基於HashMap的實現,key表示set容器中國的值,value都是一個相同的對象,HashMap的put方法。
TreeSet:基於紅/黑樹狀結構實現,繼承於NavigableSet介面,NavigableSet也就是SortedSet的擴充,具有了為給定搜尋目標報告最接近匹配項的導航方法。
LinkedHashSet:繼承與HashSet類,實現了Set介面,具有可預知迭代順序的 Set 介面的雜湊表和連結清單實現。此實現與 HashSet 的不同之外在於,後者維護著一個運行於所有條目的雙重連結清單。此連結清單定義了迭代順序,即按照將元素插入到 set 中的順序(插入順序)進行迭代。
ArrayList:實現了List介面,底層基於數組實現,對元素的隨機訪問速度較快,但是插入和刪除操作速度較慢。
LinkedList:實現了List介面和Deque介面,底層是雙重鏈表實現,對於元素的插入和刪除操作較快,但是隨機訪問的效能較差。當通過隊列使用時,LinkedList表現為一個FIFO隊列。
ArrayDeque:實現了Deque,是Deque介面一個非常高效的基於數組的實現。
PriorityQueue:是一個基於優先順序堆的無界優先順序隊列
HashMap:基於雜湊表的Map介面的實現,允許使用NULL值和key,除了非同步和可以使用null之外,和HashTable大致相同,
TreeMap:基於紅/黑樹狀結構的NavigableMap實現,其中的映射根據其鍵的自然順序或者建立的時候提供的Comparator進行排序。
LinkedHashMap:Map介面的雜湊表和鏈表實現,具有可預期的迭代順序。
_________________________________________________________________________________________________________________________________
封裝實作類別 在java.util.Collections工具類中提供了一系列的靜態內部類容器,這些內部類也實現了Collection介面,並且具有各自的特性,可以分為以下三類: Collections.unmodifiableInterface:返回指定Interface類型的容器,但是不允許使用者去修改它們。相當於原來容器的一個不能修改的視圖。Collections.synchronizedInterface:返回指定interface類型的容器,但是是安全執行緒的。Collections.checkedInterface:返回指定 interface 的一個動態型別安全視圖。試圖插入一個錯誤類型的元素將導致立即拋出ClassCastException。 ___________________________________________________________________________________________________________________________________
基於特點目的的實現:
WeakHashMap:我們說容器是用來儲存對象的,更準確的說是用來儲存對象的引用,如果一個長生命週期的容器,保持著一個無用對象的引用,就會造成GC無法回收。weakHashMap以弱鍵 實現的基於雜湊表的 Map。在 WeakHashMap 中,當某個鍵不再正常使用時,將自動移除其條目。更精確地說,對於一個給定的鍵,其映射的存在並不阻止記憶體回收行程對該鍵的丟棄,這就使該鍵成為可終止的,被終止,然後被回收。丟棄某個鍵時,其條目從映射中有效地移除,因此,該類的行為與其他的Map 實現有所不同。 IdentityHashMap:此類利用雜湊表實現Map 介面,比較鍵(和值)時使用引用相等性代替對象相等性。換句話說,在 IdentityHashMap 中,若且唯若 (k1==k2) 時,才認為兩個鍵 k1 和 k2 相等。 CopyOnWriteArrayList:ArrayList的一個安全執行緒的變體,其中所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的,一般需要很大的開銷。CopyOnWriteArraySet:內部使用CopyOnWriteArrayList的Set EnumSet:與枚舉類型一起使用的專用的Set實現。枚舉 set 中所有鍵都必須來自單個枚舉類型,該枚舉類型在建立 set 時顯式或隱式地指定。
EnumMap:與枚舉類型一起使用的專用的Map實現。枚舉映射中所有鍵都必須來自單個枚舉類型,該枚舉類型在建立映射時顯式或隱式地指定。枚舉映射在內部表示為數組。此表示形式非常緊湊且高效。
——————————————————————————————————————————————————————————————————————用於並發用用的實作類別:
ConcurrentLinkedQueue:一個基於連結節點的無界的安全執行緒的隊列,按照FIFO原則對元素進行排序。 ConcurrentHashMap:支援擷取的完全並發和更新的所期望可調整並發的雜湊表,是基於非阻塞實現的。 LinkedBlockingQueue:一個基於已連結節點的、範圍任意的blocking queue,也是按照FIFO排序元素。 PriorityBlockingQueue:一個帶有優先順序的阻塞隊列的實現。
其他的並發容器可以在java.util.concurrent包下面找到
Java Collections Framework