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 =
|