1. 程式人生 > >list集合 轉載自:超超boy

list集合 轉載自:超超boy

上篇總結了Set集合,這回總結下List集合。。。。先來框架圖:

一、List集合

List集合代表一個元素有序,可重複的集合,集合中每個元素都有對應的順序索引。List介面中增加了一些根據索引操作元素的方法:

   void add(int index,E element )  在列表的指定位置插入該元素。

   boolean addAll(int index,Collection c)  將集合c包含的所有元素都插入到List集合的index處。

   Object get(int index)    返回集合index索引出的元素。

  。。。。。詳見

1.ListIterator介面:List額外提供的一個listIterator()方法,提供了專門操作List的方法。

 ListIterator介面在Iterator的基礎上增加了如下方法:

 boolean hasPrevious(): 返回該迭代器關聯的集合是否還有上一個元素。

 Object previous(): 返回該迭代器的上一個元素。

 void add((E e): 在指定位置插入一個元素。

 示例:

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import  java.util.*;   public  class  TestListIterator {      public  static
  void  main(String[] args)      {          String[] books = {              "我是帥哥" ,              "帥哥是我"          };          List bookList =  new  ArrayList();          for  ( int  i =  0 ; i < books.length ; i++ )          {              bookList.add(books[i]);          }          ListIterator lit = bookList.listIterator();          while  (lit.hasNext())          {              System.out.println(lit.next());              lit.add( "-------分隔符-------" );   //加入一個元素          }          System.out.println( "==========下面開始反向迭代===========" );          while (lit.hasPrevious())          {              System.out.println(lit.previous());          }      } }

 輸出結果:

      我是帥哥
      帥哥是我
      ==========下面開始反向迭代===========
      -------分隔符-------
      帥哥是我
     -------分隔符-------
     我是帥哥                                       

輸出完成 (耗時 0 秒) - 正常終止

2.ArrayList實現類和Vector實現類:

ArrayList和Vector是基於陣列實現的list類,所以ArrayList和Vector封裝了一個動態的,允許再分配的Object[]陣列,不指定的話長度預設為10。ArrayList和Vector物件使用initialCapacity引數來設定該陣列的長度,當向集合新增大量元素時,可以使用ensureCapac(int minCapacity)方法一次性的增加initialCapacity。

ArrayList和Vector在用法上幾乎完全相同,但Vector比較古老,方法名比較長,最好是不使用。ArrayList是執行緒不安全的,Vector是執行緒安全的,但這個完全可以手動將一個ArrayList變成執行緒安全的。

ArrayList示例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import  java.util.*;   public  class  TestList {      public  static  void  main(String[] args)      {          List books =  new  ArrayList();          //向books集合中新增三個元素          books.add( new  String( "輕量級J2EE企業應用實戰" ));          books.add( new  String( "Struts2權威指南" ));          books.add( new  String( "基於J2EE的Ajax寶典" ));          System.out.println(books);          //將新字串物件插入在第二個位置          books.add( 1  new  String( "ROR敏捷開發最佳實踐" )); //add是插入,插入到當前位置,當前的元素向後退,並沒有覆蓋!          for  ( int  i =  0  ; i < books.size() ; i++ )          {              System.out.println(books.get(i));          }          System.out.println( "size:" +books.size());          //刪除第三個元素          books.remove( 2 );          System.out.println(books);          //判斷指定元素在List集合中位置:輸出1,表明位於第二位          System.out.println(books.indexOf( new  String( "ROR敏捷開發最佳實踐" ))); //1          //將第二個元素替換成新的字串物件          books.set( 1 new  String( "Struts2權威指南" ));          System.out.println(books);          //將books集合的第二個元素(包括)到第三個元素(不包括)擷取稱子集合          System.out.println(books.subList( 1  2 ));        } }

  輸出結果:

---------- java執行 ----------
[輕量級J2EE企業應用實戰, Struts2權威指南, 基於J2EE的Ajax寶典]
輕量級J2EE企業應用實戰
ROR敏捷開發最佳實踐
Struts2權威指南
基於J2EE的Ajax寶典
size:4
[輕量級J2EE企業應用實戰, ROR敏捷開發最佳實踐, 基於J2EE的Ajax寶典]
1
[輕量級J2EE企業應用實戰, Struts2權威指南, 基於J2EE的Ajax寶典]
[Struts2權威指南]

輸出完成 (耗時 0 秒) - 正常終止

二、Queue集合

Queue用於模擬佇列這種資料結構,先進先出。

Queue介面定義的方法如下:

 boolean add(E e):   將指定的元素插入此佇列(如果立即可行且不會違反容量限制),在成功時返回true,如果當前沒有可用的空間,則丟擲 IllegalStateException

 E element(): 獲取佇列頭部元素,但不刪除該元素。

 boolean offer(E e):  將指定的元素插入此佇列,當使用有容量限制的佇列時,此方法通常要優於add(E)

 E peek():   獲取但不移除此佇列的頭;如果此佇列為空,則返回 null

 E poll(): 獲取並移除此佇列的頭,如果此佇列為空,則返回 null

E remove(): 獲取並移除此佇列的頭。

1.PriorityQueue實現類

PriorityQueue是一個比較標準的佇列實現類,之所以說比較標準,而不是絕對標準,是因為PriorityQueue儲存佇列元素的順序並不是按加入佇列的順序,而是按佇列元素的大小進行重新排序。

示例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import  java.util.*;   public  class  TestPriorityQueue {      public  static  void  main(String[] args)      {          PriorityQueue pq =  new  PriorityQueue();          //下面程式碼依次向pq中加入四個元素          pq.offer( 6 );          pq.offer(- 3 );          pq.offer( 9 );          pq.offer( 0 );          //輸出pq佇列,並不是按元素的加入順序排列,而是按元素的大小順序排列          System.out.println(pq);          //訪問佇列第一個元素,其實就是佇列中最小的元素:-3          System.out.println(pq.peek());      } }

  輸出結果:

---------- java執行 ----------
[-3, 0, 9, 6]
-3

輸出完成 (耗時 0 秒) - 正常終止

2.Deque介面與ArrayQueue實現類

Deque介面是Queue介面的子介面,它代表一個雙端佇列,Deque接口裡定義了一些雙端佇列的方法,允許從兩端來操作佇列的元素。

Void addFirst(Object e):將指定元素插入該雙端佇列的開頭。

Void addLast(Object e):將指定佇列插入該雙端佇列的末尾。

Iterator descendingIterator():返回該雙端佇列對應的迭代器,該迭代器將以逆向順序來迭代佇列中的元素。

Object getFirst(): 獲取但不刪除佇列的第一個元素。

詳細參考api

ArrayQueue是Deque介面的典型實現類,他是一個基於陣列實現的雙端佇列,底部也是採用動態的、可重新分配的Object[]陣列儲存集合元素。

示例:把ArrayQueue當”棧“使用

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import  java.util.*;   public  class  ArrayDequeTest {      public  static  void  main(String[] args)      {          ArrayDeque stack =  new  ArrayDeque();          //依次將三個元素push入棧          stack.push( "java" );          stack.push( "java EE" );          stack.push( "Android" );          System.out.println(stack);   //輸出          //訪問第一個元素,但不將其pop出棧          System.out.println(stack.peek()); //          //          System.out.println(stack);          //pop出第一個元素          System.out.println(stack.pop());           //          System.out.println(stack);      } }

  輸出結果:

[Android, java EE, java]
Android
[Android, java EE, java]
Android
[java EE, java]

**在現在的程式中需要使用“棧”這種資料結構時,推薦使用ArrayDeque或LinkedList,而不是Stack。

3.LinkedList實現類

LinkedList實現了List介面和Deque介面(好像圖上沒有畫出來。。。。。),因此他是一個List集合還可以被當成雙端佇列來使用。

 LinkedList與ArrayList,ArrayDeque的實現機制完全不同,ArrayList、ArrayDeque內部以陣列的形式來儲存集合中的元素,因此隨機訪問集合元素時有較好的效能;而LinkedList內部以連結串列的形式來儲存集合中的元素,因此隨機訪問效能較差,但是插入、刪除元素時非常快。

示例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import  java.util.*;   public  class  TestLinkedList {      public  static  void  main(String[] args)      {          LinkedList books =  new  LinkedList();          //將字串元素加入佇列的尾部          books.offer( "Java" );          //將一個字串元素入棧          books.push( "J2EE" );          //將字串元素新增到佇列的頭部          books.offerFirst( "Android" );          for  ( int  i =  0 ; i < books.size() ; i++ )          {              System.out.println(books.get(i));          }          //訪問、並不刪除佇列的第一個元素          System.out.println(books.peekFirst());          //訪問、並不刪除佇列的最後一個元素          System.out.println(books.peekLast());          //採用出棧的方式將第一個元素pop出佇列          System.out.println(books.pop());          //下面輸出將看到佇列中第一個元素被刪除          System.out.println(books);          //訪問、並刪除佇列的最後一個元素          System.out.println(books.pollLast());          //下面輸出將看到佇列中只剩下中間一個元素:輕量級J2EE企業應用實戰          System.out.println(books);        } }

  輸出結果:

Android
J2EE
Java
Android
Java
Android
[J2EE, Java]
Java
[J2EE]

**上面的程式碼分別示範了雙端佇列,棧的用法,所以LinkedList是一個功能非常強大的集合類。

4.各種線性表的效能分析:

 

實現機制

隨機訪問排名

迭代操作排名

插入操作排名

刪除操作排名

陣列

連續記憶體區儲存元素

1

不支援

不支援

不支援

ArrayList/ArrayDeque

以陣列儲存元素

2

2

2

2

Vector

以陣列儲存元素

3

3

3

3

LinkedList

連結串列儲存元素

4

1

1

1

 

  示例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import  java.util.*; /**   * Description:   * <br/>Copyright (C), 2005-2008, Yeeku.H.Lee   * <br/>This program is protected by copyright laws.   * <br/>Program Name:   * <br/>Date:   * @author  Yeeku.H.Lee [email protected]   * @version  1.0   */ public  class  TestPerformance {      public  static  void  main(String[] args)      {          //建立一個字串陣列          String[] tst1 =  new  String[ 900000 ];          //動態初始化陣列元素          for  ( int  i =  0 ; i <  900000 ; i++)          {              tst1[i] = String.valueOf(i);          }                    ArrayList al =  new  ArrayList();          //將所有陣列元素加入ArrayList集合中          long  start = System.currentTimeMillis();          for  ( int  i =  0 ; i <  900000  ; i++)          {              al.add(tst1[i]);          }          System.out.println( "ArrayList集合新增元素的時間:"  + (System.currentTimeMillis() - start));          LinkedList ll =  new  LinkedList();          //將所有陣列元素加入LinkedList集合中          start = System.currentTimeMillis();          for  ( int  i =