前幾天其實一直在學習關於linux的內容和kvm虛擬化的知識。今天有時間來回顧一下集合相關的知識,接下來我將帶大家一起來回顧一起集合關聯的知識。
不要辜負自己花費時間做的事情,只有用心才能得到真心的回報!
關於java集合框架的知識:大致可分為Set、List和Map三種體系,其中Set代表無序、不可重復的集合;List代表有序、重復的集合;而Map則代表具有映射關系的集合。Java 5之后,增加了Queue體系集合,代表一種隊列集合實現。
Java集合框架主要由Collection和Map兩個根接口及其子接口、實現類組成。
集合類划分為兩個大的部分:一種是可以按照一定順序進行迭代訪問的集合類;一種是通過名值對的映射建立關系進行訪問的集合類
一、Collection接口概述
1.1、collection接口概述
Collection接口是所有后續集合類型的一個公共抽象定義。它本身沒有一個直接的實現,更多的是各種不同的集合類型在它的基礎上繼承了更多特殊的特性並做了一個實現。
Collection接口里主要定義了一些作為集合類型比較通用的方法,比如說size, isEmpty, add, remove等。作為集合類型比較通用的一個定義,它主要用在一些需要比較高級別抽象的地方。比如說我們需要可以對所有集合類型進行通用操作。
1.2、Collection接口定義的方法
(1)增加、add(E e) - 返回值為boolean(是否添加成功)。
(2)清除、clear() - 除去此數組的所有操作。
(3)是否包含某一元素、contains(Object o) - 如果包含返回為true(可以用於進行if判斷),如果集合里邊的元素為自定義
類的話需要重寫自定類的equals方法(contains方法就是基於equals實現的)否則比較的是地址。
(4)比較此collection與指定對象是否相等、equals(Object o) - 返回值為boolean(true為相等)。
(5)此collection是否包含某元素、isEmpty() - 返回值為boolean(true為不包含)。
(6)獲取此collection的迭代器、iterator() - 用於遍歷集合(此迭代器只能遍歷集合,不能對集合進行修改,否則會報並發
修改異常-ConcurrentModificationException)。
(7)刪除指定元素、remove(Object o) - 返回值為boolean(true表示刪除成功)。
(8)返回元素數(集合的長度)、size() - 返回值為int(集合中元素的個數)。
(9)返回此集合中所有元素的數組、toArray() - 返回值是一個數組。
二、Collection的子接口概述
2.1、set接口
在常用的集合類型中,HashSet, TreeSet等具體的實現往往不一樣。比如說HashSet本身的實現是引用了HashMap作為內部的元素。如果我們仔細檢查他們的結構實現,會發現有的類型我們也可以通過foreach的循環來遍歷。
這是因為他們有的在實現Set定義接口的范圍同時也繼承了實現Collection接口的部分。可以說是兩者兼有之。
在上面這些集合類型中,基於Hash表實現的主要有HashSet, LinkedHashSet。基於紅黑樹實現的有TreeSet.
特點:無順序,不可重復
1)HashSet
不能保證元素的排列順序,加入的元素要特別注意hashCode()方法的實現。
HashSet不是同步的,多線程訪問同一步HashSet對象時,需要手工同步
集合元素值可以是null。
2)LinkedHashSet
LinkedHashSet類也是根據元素的hashCode值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序。與HashSet相比,特點:
對集合迭代時,按增加順序返回元素。
性能略低於HashSet,因為需要維護元素的插入順序。但迭代訪問元素時會有好性能,因為它采用鏈表維護內部順序。
3)TreeSet
TreeSet類是SortedSet接口的實現類。因為需要排序,所以性能肯定差於HashSet。
4)EnumSet類
專為枚舉類設計的集合類,EnumSet中的所有元素都必須是指定枚舉類型的枚舉值
2.2、List接口
List類型的數據結構算是我們平時接觸最多而且看起來最簡單的數據結構類型。最常用的兩種是ArrayList和LinkedList,也就是我們常說的線性表和鏈表。
1)LinkedList類
內部使用鏈表的形式來存儲數據,在增加和刪除數據上面性能更好
它實現了List接口和Deque接口,說明它具有兩邊接口的特性,因此它可以當作一個雙端隊列來用,也可以當作棧來用,並且它是以鏈表的形式來實現的,所以查詢性能差,但是增加和刪除操作性能高。
2)ArrayList類
內部使用數組來存儲數據,也就相當於數據結構的順序表存儲,在查詢數據上面性能好,
3)Vertor類
跟ArrayList相比,它是線程安全的,而ArrayList是線程不安全的,
4)Stack類繼承Vertor類
看名字,其實就是方便模擬“棧”這種數據結構
2.3、Queue
用於模擬隊列這種數據結構,然后該接口中聲明了一些基本操作的方法。例如:add、offer、remove等
1)PriorityQueue類
PriorityQueue保存隊列元素的順序並不是按照加入隊列的順序,而是按隊列元素的大小重新排序
2)Deque接口
Deque代表一個雙端隊列,可以當作一個雙端隊列使用,也可以當作“棧”來使用,因為它包含出棧pop()與入棧push()方法。
3)ArrayDeque類為Deque的實現類
也就是實現了Deque接口中定義的方法,解釋跟deque差不多
2.4、各種線性表中選擇策略
數組:是以一段連續內存保存數據的;隨機訪問是最快的,但不支持插入、刪除、迭代等操作。
ArrayList與ArrayDeque:以數組實現;隨機訪問速度還行,插入、刪除、迭代操作速度一般;線程不安全。
Vector:以數組實現;隨機訪問速度一般,插入、刪除、迭代速度不太好;線程安全的。
LinkedList:以鏈表實現;隨機訪問速度不太好,插入、刪除、迭代速度非常快。
三、Map集合框架概述
Map接口:定義一些基本的操作,例如put(key,value), containKey(Object key)等一系列操作。
使用key、value鍵值對的形式進行訪問的集合類
3.1、Map接口概述
1)HashMap類和Hashtable類對比,
一般使用HashMap,因為Hashtable類是很古老的,據查都不建議用。平常我們也是用HashMap
HashMap類是線程不安全的,而Hashtable是線程安全的
HashMap類可以使用null作為key和value,而Hashtable不可以
2)Properties類繼承Hashtable類
增加了額外的一些方法,例如:load(InputStream inStream)從屬性文件加載key-value等方法。
可以將key-value用xml文件的格式保存,可能就是跟xml文件打一些交道
3)LinkedHashMap類繼承HashMap類
LinkedHashMap從HashMap類繼承而來。以鏈表來維護內部順序。很多方面跟LinkedHashSet類似。LinkedHashMap它可以記住key-value對的添加時的順序, 同時避免使用TreeMap時性能受到的影響。
4)SortedMap接口和TreeMap實現類
類似於SortedSet及TreeSet,TreeMap也可以自定義比較器(Comparable)實現定制排序。它的額外提供的方法也與TreeSet類似,增加了訪問第一個、前一個、后一個、最后一個key-value對的方法,並
提供了從TreeMap中提取子集的方法。TreeMap不允許null作為key,要不然怎么比較呢?
5)IdentityHashMap類
與HashMap的不同在於,只有兩個key嚴格相等(key1 == key2)時,IdentityHashMap才認為兩個key相等;而對於普通HashMap而言,只要key1.equals(key2)且hashCode相同即可。同樣允許null值,不能保證順序。
6)EnumMap類
EnumMap是一個與枚舉類一起使用的Map實現。它的key必須是單個枚舉類的枚舉值。EnumMap不允許使用null作為key,但可作為value。
3.2、各種map類選擇策略
正常情況使用HashMap,而不是Hashtable。
如果考慮排序,那么考慮使用TreeMap。通常TreeMap比HashMap等在插入、刪除操作時要慢不少,因為它需要在底層采用紅黑樹來管理key-value對。
如果考慮插入時的順序,那么使用LinkedHashMap是個不錯的選擇。
如果想優化垃圾回收,建議使用WeakHashMap實現類(本文未提及);要求key完全匹配(同一對象),則使用IdentityHashMap;還有枚舉類不多說了。
關於null值:Hashtable不允許key為null,也不允許value為null;TreeMap與EnumMap不允許key為null;HashMap及其子類LinkedHashMap,IdentityHashMap允許key為null。