一、Java 集合,Collection介面框架圖
Java集合大致可分為Set、List和Map三種體系,其中Set代表無序、不可重複的集合;List代表有序、可重複的集合;而Map則代表具有對映關係的集合。Java 5之後,增加了Queue體系集合,代表一種佇列集合實現。Java集合框架主要由Collection和Map兩個根介面及其子介面、實現類組成。
1. Collection 介面繼承樹
2.Collection介面是Set、List和Queue介面的父介面,基本操作包括:
- add(Object o):增加元素
- addAll(Collection c):…
- clear():…
- contains(Object o):是否包含指定元素
- containsAll(Collection c):是否包含集合c中的所有元素
- iterator():返回Iterator物件,用於遍歷集合中的元素
- remove(Object o):移除元素
- removeAll(Collection c):相當於減集合c
- retainAll(Collection c):相當於求與c的交集
- size():返回元素個數
- toArray():把集合轉換為一個數
3.Collection的遍歷可以使用Iterator介面或者是foreach迴圈來實現
4.List集合
List子介面是有序集合,所以與Set相比,增加了與索引位置相關的操作:
- add(int index, Object o):在指定位置插入元素
- addAll(int index, Collection c):…
- get(int index):取得指定位置元素
- indexOf(Obejct o):返回物件o在集合中第一次出現的位置
- lastIndexOf(Object o):…
- remove(int index):刪除並返回指定位置的元素
- set(int index, Object o):替換指定位置元素
subList(int fromIndex, int endIndex):返回子集合
4.1ArrayList集合
4.2LinkList集合
5. Set集合
Set集合不允許包含相同的元素,而判斷兩個物件是否相同則是根據hashCode() 方法和 equals()方法。
5.1HashSet集合
HashSet類是Set介面的典型實現類。特點:
1. 不能保證元素的排列順序,加入的元素要特別注意hashCode()方法的實現。
2. HashSet不是同步的,多執行緒訪問同一步HashSet物件時,需要手工同步。
3. 集合元素值可以是null。
5.2SortedSet介面及TreeSet集合
TreeSet類是SortedSet介面的實現類。因為需要排序,所以效能肯定差於HashSet。與HashSet相比,額外增加的方法有:
1. first():返回第一個元素
2. last():返回最後一個元素
3. lower(Object o):返回指定元素之前的元素
4. higher(Obect o):返回指定元素之後的元素
5. subSet(fromElement, toElement):返回子集合
- TreeSet中儲存的型別必須是一致的,不能一下存int,一下又存string
- TreeSet在遍歷集合元素時,是有順序的【預設自然升序排序】(我的理解,如果存的字母,按字典序排列)
排序:當向TreeSet中新增自定義物件時,有2種排序方法,1:自然排序 2、定製排序
– 自然排序:要求自定義類實現java.lang.Comparable介面並重寫compareTo(Object obj)方法,否則自定義類新增到TreeSet集合中時報錯。在此方法中,指明按照自定義類的哪個屬性進行排序
– 定製排序:要求重寫 equals() 和 hashCode() 方法,通過自定義規則比較兩個物件是否是同一個物件
##在使用定製排序或是自然排序時,在其用到的類中都要重寫hashCode()與equals()方法
6.Queue子介面
Queue用於模擬佇列這種資料結構,實現“FIFO(First in first out 先進先出)”等資料結構。通常,佇列不允許隨機訪問佇列中的元素。
Queue 介面並未定義阻塞佇列的方法,而這在併發程式設計中是很常見的。BlockingQueue 介面定義了那些等待元素出現或等待佇列中有可用空間的方法,這些方法擴充套件了此介面。
Queue 實現通常不允許插入 null 元素,儘管某些實現(如 LinkedList)並不禁止插入 null。即使在允許 null 的實現中,也不應該將 null 插入到 Queue 中,因為 null 也用作 poll 方法的一個特殊返回值,表明佇列不包含元素。
基本操作:
- boolean offer(E e): 將指定的元素插入此佇列(如果立即可行且不會違反容量限制),當使用有容量限制的佇列時,此方法通常要優於 add(E),後者可能無法插入元素,而只是丟擲一個異常。推薦使用此方法取代add
- E poll(): 獲取頭部元素並且刪除元素,佇列為空返回null;推薦使用此方法取代remove
- E element(): 獲取但是不移除此佇列的頭
- E peek(): 獲取佇列頭部元素卻不刪除元素,佇列為空返回null
@Test
public void testQueue() {
Queue<String> queue = new LinkedList<String>();
queue.offer("1.你在哪兒?");
queue.offer("2.我在這裡。");
queue.offer("3.那你又在哪兒呢?");
String str = null;
while ((str = queue.poll()) != null) {
System.out.println(str);
}
}
6.1PriorityQueue類
PriorityQueue儲存佇列元素的順序並不是按照加入佇列的順序,而是按佇列元素的大小重新排序。當呼叫peek()或者是poll()方法時,返回的是佇列中最小的元素。當然你可以與TreeSet一樣,可以自定義排序。自定義排序的一個示範:
@Test
public void testPriorityQueue() {
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(20, new Comparator<Integer>() {
public int compare(Integer i, Integer j) {
// 對數字進行奇偶分類,然後比較返回;偶數有較低的返回值(對2取餘數然後相減),奇數直接相減。
int result = i % 2 - j % 2;
if (result == 0)
result = i - j;
return result;
}
});
// 倒序插入測試資料
for (int i = 0; i < 20; i++) {
pq.offer(20 - i);
}
// 列印結果,偶數因為有較低的值,所以排在前面
for (int i = 0; i < 20; i++) {
System.out.println(pq.poll());
}
}
複製程式碼
輸出:
2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19,
6.2Deque子介面與ArrayDeque類
Deque代表一個雙端佇列,可以當作一個雙端佇列使用,也可以當作“棧”來使用,因為它包含出棧pop()與入棧push()方法。
ArrayDeque類為Deque的實現類,陣列方式實現。方法有:
- addFirst(Object o):元素增加至佇列開頭
- addLast(Object o):元素增加至佇列末尾
- poolFirst():獲取並刪除佇列第一個元素,佇列為空返回null
- poolLast():獲取並刪除佇列最後一個元素,佇列為空返回null
- pop():“棧”方法,出棧,相當於removeFirst()
- push(Object o):“棧”方法,入棧,相當於addFirst()
- removeFirst():獲取並刪除佇列第一個元素
- removeLast():獲取並刪除佇列最後一個元素
6.3實現List介面與Deque介面的LinkedList類
LinkedList類是List介面的實現類,同時它也實現了Deque介面。因此它也可以當做一個雙端佇列來用,也可以當作“棧”來使用。並且,它是以連結串列的形式來實現的,這樣的結果是它的隨機訪問集合中的元素時效能較差,但插入與刪除操作效能非常出色。
6.4深入理解佇列拓展
7.各種線性表選擇策略
- 陣列:是以一段連續記憶體儲存資料的;隨機訪問是最快的,但不支援插入、刪除、迭代等操作。
- ArrayList與ArrayDeque:以陣列實現;查詢快,增刪慢;執行緒不安全。
- LinkedList:以連結串列實現;查詢慢,增刪快。
- Queue 用來存放 等待處理元素 的集合,這種場景一般用於緩衝、併發訪問。(BlockingQueue 詳解)