前言
最近在Leetcode刷個幾題,使用到集合(Collection)物件的頻率甚高,顧名思義就是把多個有關聯的資料存放在Collection裡面,而這些資料叫做元素(Elements),同時也就是物件。因為常常會不小心忘記有一些集合的宣告方法或具有哪些方法,因此,這邊來記錄一下我在Leetcode上最常用到的幾個Collection。
Collection
集合物件(Collections)是將一群相關的資料聚集在一個物件當中,且可以對這些資料做存放及排序等操作,其實就類似陣列,所以Collection也被人叫做動態陣列(dynamically array),最重要的是它具備許多有效和方便的功能。下列為Collection的特色
- 屬於Java的java.util.*套件
- 在集合裡面的成員(Element)要是物件(Object)型態,如果要使用基本型別的話要用Wrapper class(但其實存放int宣告的變數還是可以,Java會幫你轉成Integer)
- 可以搭配使用到泛型(genric),讓編譯時就可以檢查元素的資料型態,所以會具有更彈性的型別安全(type safety)檢查機制,且同時可以減少轉型(Casting)的使用
- 實作Collection的物件有許多都是常見的資料結構
下面這張圖是集合物件之間的關係圖
Stack
堆疊(Stack)繼承Vector類別,實現了一種資料結構為後進先出(LIFO)的類別。因為Stack繼承父類別Vector的的add(Element e)及isEmpty()等方法,但使用Stack類別自己實作的push(Element e)及empty()方法可以增加程式的可讀性及目的性 (引用link )。
1 2 3 4 5 6 7 8 9 10 11 12
| Stack<Integer> stack = new Stack<Integer>(); stack.push(10); stack.push(null); stack.push(5); stack.push(1); System.out.println(stack); System.out.println(stack.size()); System.out.println(stack.indexOf(1)); System.out.println(stack.peek()); int t = stack.pop(); System.out.println(stack); System.out.println(stack.search(10));
|
另外還要注意當stack為空時,如果使用peek()和pop()會拋出java.util.EmptyStackException
1 2 3 4 5 6 7
| Stack<Integer> stack = new Stack<Integer>(); try { stack.peek(); stack.pop(); } catch (EmptyStackException e) { System.out.println("Stack為空"); }
|
Queue
貯列(Queue)與Stack相反,資料型態為先進先出(FIFO)的類別,這邊要注意的地方是Queue為一個介面,要由LinkedList或PriorityQueue來實作,還有Queue因為繼承至Collection介面,所以也具備一些相同的等方法,但通常為了可讀性及安全性,還是會使用Queue自己的offer()及poll()等方法,而且官方文件有提到offer()、poll()和peek()遇到操作失敗時,不同於add()、remove()及element()會直接拋出Exception,反而是會返回特定值,像是offer()會返回boolean值 ; poll()遇queue為空,則是會回傳null,否則就回傳最前面的那個物件,並再回傳後刪除此物件 ; peek()也是當queue為空時,即返回一個null,不然就回傳queue最前面那一個物件。Queue有自己的一個不放參數直接remove()方法,其表示移除最接近的元素,但要小心,如果遇到空的Queue,則會拋出java.util.NoSuchElementException
LinkedList |
PriorityQueue |
最常見實作Queue的類別,具備貯列(Queue)基本的原則(FIFO),規則為每次都從尾端加入,並從前端來取出元素,來達到類似排隊的效果 |
從行為來看PriorityQueue已經沒有貯列(Queue)基本的原則(FIFO),因為他的排列順序是根據元素的小到大,意思就是每次取出(poll)的元素都是Queue中數值為小的那一個 |
可存放null元素 |
不能存放null元素,會拋出java.lang.NullPointerException |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Queue<Integer> queue = new LinkedList<Integer>(); queue.offer(1); queue.offer(5); queue.offer(3); queue.offer(2); System.out.println(queue); System.out.println(queue.poll()); System.out.println(queue); System.out.println(queue.peek()); Queue<Integer> queue = new PriorityQueue(); queue.offer(1); queue.offer(5); queue.offer(3); queue.offer(2); System.out.println(queue); System.out.println(queue.poll()); System.out.println(queue); System.out.println(queue.peek());
|
Dequeue
1
| Deque deque = new ArrayDeque();
|
通用方法
Iterable 介面
方法 |
說明 |
回傳型態 |
hasNext() |
判斷迭代器還有沒有元素,有的話就回傳true |
boolean |
next() |
將迭代器的元素傳回,並指向下一個元素,只能從前往後取值(不可逆) |
Object() |
remove() |
刪除iterator.next()方法目前指到的元素,所以可以在迴圈裏面放在next()的後面,就可以清空集合物件的元素了 |
void |
1 2 3 4 5 6 7 8 9
| List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }
|
Collection 介面
方法 |
說明 |
回傳型態 |
remove(Object o) |
刪除放在參數的o物件,成功回傳true |
boolean |
remove(int i) |
移除索引值為i的物件,成功則回傳此物件,若超出集合物件的索引時會拋出java.lang.IndexOutOfBoundsException |
泛型所宣告的物件型態<E> |
indexOf(Object o) |
指參數的物件在集合物件從前面數來第幾個索引(從0開始),而還有一個是lastIndexOf(Object o)則是從後面來找尋,若都沒有符合的那一個物件就回傳一個-1,注意這是具有索引的集合物件才有的方法,像是Set或Map就沒有 |
int |
size() |
回傳集合的元素有多少個元素 |
int |
iterator() |
將Collection變成iterator物件,以便來取得集合內所有的值,通常會搭配一個迴圈,然後條件判斷呼叫已經iterator()的參考變數的hasNext(),來判斷是否還有元素可以迭代出來,迴圈裡面使用參考變數的next()來取集合內的值 |
Iterator |
isEmpty() |
檢視集合物件是否為空 |
boolean |