標籤:java集合 deque linkedlist
這篇部落客要介紹List集合和Queue集合
一.List集合
List集合是一個有序的可重複的集合,集合中的每個元素都對應一個索引,我們可以通過索引來訪問List集合中的資料(其實可以看成一個長度可變的數組)。
List作為Collection的子介面,支援Collection的所有操作,但因為List是有序的所以新增加了一些新的操作,主要是根據索引來插入,刪除,替換元素的方法。List通過equals()方法判斷對象是否相等。如下面的代碼所示:
package lkl;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.List;public class ListTest { public static void main(String[] args){ Collection c = new HashSet(); c.add("java"); c.add("c"); c.add("c++"); List ls = new ArrayList(); ls.add(1); ls.add(1); ls.add(-1); ls.add(3); ls.add(3); System.out.println(ls); ///void add(int index,Object e) ///將元素e插入到List中下標為index處,index值不能大於List原先的長度 ls.add(2, 4); System.out.println(ls); ///void addAll(int index,Collection c) ///將集合c中所有元素都插入到List的index處 ls.addAll(2,c); System.out.println(ls); ///Object get(int index) ///返回List index處的元素,這個方法可結合for迴圈遍曆List for(int i=0;i<ls.size();i++) System.out.print(ls.get(i)+" "); System.out.println(); ///int indexOf(Object o):返回元素o在集合中第一次出現的位置 ///int lastIndexOf(Object o):返回元素o在集合中最後一次出現的位置 System.out.println(ls.indexOf(3)); System.out.println(ls.lastIndexOf(3)); ///Object remove(int index):刪除並返回index處的元素 System.out.println(ls.remove(2)); System.out.println(ls); ///Object set(int index,Object e) ///用e替換index處的對象,並返回原對象 System.out.println(ls.set(1,3)); System.out.println(ls); ///List subList(int index1,int index2) ///返回處於index1和index2之間元素組成的子集 System.out.println(ls.subList(2, 5)); }}
對於List,由於它是有序的,所以List提供了一個額外的遍曆方法lsitIterator();該方法提供了反向迭代的功能,並且還可以在遍曆過程中向集合中增加元素。其相比Iterator介面增加的方法如下:
boolean hasPrevious():返回該迭代器關聯的集合是否還有上一個元素。
Object previous() :返回該迭代器的上一個元素
void add() :向指定位置插入一個元素
下面的代碼示範了這些操作的效果:
package lkl;import java.util.ArrayList;import java.util.List;import java.util.Iterator;import java.util.ListIterator;public class ListIteratorTest { public static void main(String[] args){ List ls = new ArrayList(); ls.add(1); ls.add(2); ls.add(3); ///聲明一個ListIterator類型的迭代器 ListIterator lt = ls.listIterator(); ///正向迭代過程 while(lt.hasNext()){ int k=(int) lt.next(); System.out.print(k+" "); ///還可以在迭代過程中插入一個元素,但插入的元素不會影響此次的遍曆 if(k==2) lt.add(4); } System.out.println(); System.out.println("下面是反向迭代過程"); ///下面開始反向迭代過程 while(lt.hasPrevious()){ System.out.print(lt.previous()+" "); } System.out.println(); }}
二.List集合的實作類別:ArrayList和Vector
ArrayList和Vector是List的兩個典型實現,完全支援前面所介紹的所有的操作。ArrayList和Vector都是基於數組實現的List類,所以ArrayList和Vector類封裝了一個動態允許再分配的Object[]數組。Arraylist和Vector對象使用initialCapacity參數來設定數組的長度,然後當數組滿了之後,其initialCapcity會自動增加;但是如果我們要向ArrayList中添加大量元素,那麼我們可以使用ecsureCapacity()方法一次性增加initialCapacity,這樣可以減少分配次數,提高效能。Object[]數組預設的長度為10.
Vector與ArrayList用法幾乎完全相同,只是Vector是一個古老的集合。
並且Vector還封裝了一個Stack子類,用來類比棧,其用法如下:
package lkl;import java.util.Stack;public class VectorStackTest { public static void main(String[] args){ ///聲明一個棧 Stack st = new Stack(); ///將元素入棧 st.push("c語言"); st.push("cpp"); st.push("java"); System.out.println(st); //返回棧頂元素,但不將其出棧 System.out.println(st.peek()); System.out.println(st); //將棧頂元素出棧,並返回 System.out.println(st.pop()); System.out.println(st); }}
三.Queue集合
Queue集合用於類比隊列,即滿足先進先出的性質。Queue的基本操作如下面的代碼所示:
package lkl;import java.util.ArrayDeque;import java.util.Queue;public class QueueTest { public static void main(String[] args){ Queue qu = new ArrayDeque(); ///void add(Object e) boolean offer(Object e) ///這兩個方法都可以將元素加入到隊列的尾部 qu.add("c++"); qu.add("c語言"); qu.add("java"); System.out.println(qu); ///Object peek():擷取隊頭元素但是不刪除該元素 ///Object poll():擷取隊頭元素並刪除該元素 System.out.println(qu.peek()); System.out.println(qu); System.out.println(qu.poll()); System.out.println(qu); }}
Queue還有一個PriorityQueue的實作類別,即平時我們用的優先隊列。
此外Queue還有一個Qeque介面,即”雙端隊列”,可以從兩端來添加和刪除元素,因此Deque的實作類別既可以當隊列使用也可以當棧使用。關於Dequeu的基本操作就不一一羅列了。Deque介面提供了一個典型的實作類別:ArrayDeque,一個基於數組的雙端隊列實現。下面示範如何將雙端隊列來當初棧使用,可以看出和前面Vector實現的棧用法是一樣的:
package lkl;import java.util.ArrayDeque;public class DequeStackTest { public static void main(String[] args){ ArrayDeque st = new ArrayDeque(); st.push(1); st.push(2); st.push(3); System.out.println(st); System.out.println(st.peek()); System.out.println(st); System.out.println(st.pop()); System.out.println(st); }}
四.LinkedList實作類別
LinkedList實作類別是List介面的實作類別,其內部用鏈表來儲存集合中的元素,因此有非常好的插入,刪除效能。而其他的List實作類別隨機訪問效能比較好。LinkedList除了具有List的基本操作外,還實現了Dequeu介面,因此它可以被當成雙端隊列來使用,也可以當成棧來使用。下面的代碼簡單示範了LinkedList集合的用法:
package lkl;import java.util.LinkedList;public class LinkedListTest { public static void main(String[] args){ LinkedList books = new LinkedList(); ///將字串加入到隊列的尾部 books.offer("c++"); ///將字串元素加入到棧的頂部 books.push("java"); ///將字串加入到隊列的頭部(相當於棧的頂部) books.offerFirst("c語言"); for(int i=0;i<books.size();i++) System.out.print(books.get(i)+" "); System.out.println(); ///訪問但不刪除棧頂的元素 System.out.println(books.peekFirst()); ///訪問但不刪除隊列最後一個元素 System.out.println(books.peekLast()); ///將棧頂的元素彈出 System.out.println(books.pop()); System.out.println(books); ///訪問並刪除隊列的最後一個元素 System.out.println(books.pollLast()); System.out.println(books); }}
java集合學習之Collection(3)