系列文章:
前言
從本篇開始阿迈,我將開始Java集合系列的梳理缴饭,本文先對(duì)集合框架中涉及到的接口,架構(gòu)绍哎,類等做一個(gè)總體展示瘟芝,后面的文章中再結(jié)合源碼分別剖析具體集合,希望能用兩個(gè)月的時(shí)間完成Java集合系列文章轧房。
Java最初版本只為最常用的數(shù)據(jù)結(jié)構(gòu)提供了很少的一組類:Vector
纸颜,Stack
,Hashtable
怀读,BitSet
與Enumeration
接口诉位。Enumeration
接口定義了從一個(gè)數(shù)據(jù)結(jié)構(gòu)得到連續(xù)數(shù)據(jù)的手段,實(shí)現(xiàn)了遍歷集合愿吹,現(xiàn)在已經(jīng)被迭代器Iterator
取代了不从。JDK1.2
版本后,Java開始提供了一組集合框架犁跪,完善了Java數(shù)據(jù)結(jié)構(gòu)椿息。
Java集合包含了以下常用的數(shù)據(jù)結(jié)構(gòu):集合(Set
,無(wú)序不可重合的集合)坷衍、列表(List
寝优,有序可重復(fù)的集合)、隊(duì)列(Queue
枫耳,隊(duì)列集合乏矾,JDK1.5
后加入)、棧(Stack
)迁杨、數(shù)組钻心、映射表(Map
,具有映射關(guān)系的集合)等铅协。Java集合類庫(kù)構(gòu)成了集合類的框架捷沸,包含了大量的接口,抽象類狐史,框架圖如下所示:
從上圖可以發(fā)現(xiàn)痒给,Java集合主要由三個(gè)接口派生出來(lái),分別是Iterator
骏全,Collection
苍柏,Map
,而Collection
又派生出List
姜贡,Set
试吁,Queue
等,可以說(shuō)是Java集合的根接口了楼咳。
迭代器接口(Iterator)
首先我們來(lái)看Iterator
接口熄捍,主要用來(lái)遍歷集合對(duì)象中的元素律秃,其包含三個(gè)方法:
public interface Iterator<E>
{
E next(); // 返回將要訪問(wèn)的下一個(gè)對(duì)象
boolean hasNext(); // 如果存在可訪問(wèn)的元素,返回true
void remove(); // 刪除上次訪問(wèn)的對(duì)象,必須緊跟在訪問(wèn)一個(gè)元素之后執(zhí)行
}
遍歷元素
通過(guò)反復(fù)調(diào)用next
方法,可以逐個(gè)訪問(wèn)集合中的每個(gè)元素瘫絮,如果到達(dá)了集合的末尾锭弊,next
方法將拋出一個(gè)NoSuchElementException
,因此在調(diào)用next
方法之前需要調(diào)用hasNext
方法判斷是否到達(dá)集合末尾柜裸。使用方法如下:
Collection<String> c = ...
Iterator<String> iter = c.iterator();
while(iter.hasNext())
{
String ele = iter.next();
...
}
從Java JDK1.5
之后缕陕,可以用for循環(huán)來(lái)執(zhí)行上述循環(huán)操作了,更加簡(jiǎn)潔疙挺,代碼如下:
for(String ele : c)
{
...
}
編譯器將“for each”循環(huán)翻譯為帶有迭代器的循環(huán)扛邑,“for each”循環(huán)適用于任何實(shí)現(xiàn)了Iterable
接口的對(duì)象,Iterable
接口只包含了一個(gè)方法:
public interface Iterable<E>
{
Iterator<E> iterator();
}
Collection
接口擴(kuò)展了Iterable
接口铐然,因此Java集合中只要實(shí)現(xiàn)了Collection
集合的接口都可以使用“for each”循環(huán)蔬崩。
刪除元素
Iterator
接口的remove
方法刪除上次調(diào)用next
方法返回的元素,與遍歷元素類似搀暑,刪除某元素前沥阳,需要判斷該元素是否有意義。正確的使用方法如下:
Collection<String> c = ...
Iterator<String> iter = c.iterator();
iter.next();
iter.remove();
可以看到先調(diào)用next
方法返回想要?jiǎng)h除的元素自点,再刪除之桐罕。如果上次訪問(wèn)之后,集合已經(jīng)發(fā)生變化桂敛,再調(diào)用remove
方法功炮,將拋出一個(gè)IllegalStateException
。
以下的使用方法都是錯(cuò)誤的:
- 沒(méi)有調(diào)用
next
方法
Iterator<String> iter = c.iterator();
iter.remove();
- 調(diào)用一次
next
方法术唬,刪除連續(xù)兩個(gè)元素
Iterator<String> iter = c.iterator();
iter.next();
iter.remove();
iter.remove();
集合接口 (Collection)
方法列表
Collection
主要包含了集合的基本操作和屬性薪伏,有兩大分支List
和Set
。其中定義了很多方法供其子類實(shí)現(xiàn)碴开,以實(shí)現(xiàn)數(shù)據(jù)操作毅该,方法列表如下圖所示:
從方法列表中可以看出,Collection
接口主要的功能有:添加元素潦牛,刪除元素眶掌,清空集合等。
iterator
方法用于返回一個(gè)實(shí)現(xiàn)了Iterator
接口的對(duì)象巴碗,使用此對(duì)象遍歷集合元素朴爬。
List接口
List是一個(gè)元素有序,可重復(fù)的集合橡淆,每一個(gè)元素都有它的索引召噩,可以通過(guò)索引來(lái)訪問(wèn)指定位置的集合元素母赵。由于List是有序集合,因此List接口中添加了一些根據(jù)索引值來(lái)操作的方法具滴。List的實(shí)現(xiàn)類有LinkedList
, ArrayList
, Vector
, Stack
凹嘲。
// List接口與Collection相比新增的方法
abstract void add(int index, E object)
abstract boolean addAll(int index, Collection<? extends E> collection)
abstract E get(int index)
abstract int indexOf(Object object)
abstract int lastIndexOf(Object object)
abstract ListIterator<E> listIterator(int index)
abstract ListIterator<E> listIterator()
abstract E remove(int index)
abstract E set(int index, E object)
abstract List<E> subList(int start, int end)
Set接口
Set
是一個(gè)不允許有重復(fù)元素的集合,其方法和Collection
相比沒(méi)有區(qū)別构韵,當(dāng)添加重復(fù)元素時(shí)會(huì)返回false周蹭,Set的實(shí)現(xiàn)類有HashSet
和TreeSet
,而HashSet
又依賴于HashMap
,實(shí)際上是通過(guò)HashMap
實(shí)現(xiàn)的疲恢;TreeSet
又依賴于TreeMap
凶朗,實(shí)際上是通過(guò)TreeMap
實(shí)現(xiàn)的。
Queue接口
Queue接口模擬了隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)显拳,先進(jìn)先出(FIFO
)棚愤,其方法摘要如下圖所示:
Map接口
Map是一個(gè)具有映射關(guān)系的集合,以“key-value
”保存數(shù)據(jù)杂数。把Map集合里的Key值放在一起就構(gòu)成了類似于Set的集合宛畦,Key值沒(méi)有順序,且不允許重復(fù)耍休,Map接口的KeySet()
方法用于返回Key值構(gòu)成的Set集合刃永;而把Map集合里的Value值放在一起就構(gòu)成了類似于List的集合,元素之間可以重復(fù)羊精。其方法摘要如下:
AbstractCollection類
其定義如下:
public abstract class AbstractCollection<E> extends Object implements Collection<E> {}
AbstractCollection
類是一個(gè)抽象類斯够,提供了 Collection
接口的大部分實(shí)現(xiàn),以最大限度地減少了實(shí)現(xiàn)此接口所需的工作喧锦,除了iterator
和 size
方法读规。
要實(shí)現(xiàn)一個(gè)不可修改的 collection
,我們只需擴(kuò)展此類燃少,并實(shí)現(xiàn) iterator
和 size
方法(iterator
方法返回的迭代器必須實(shí)現(xiàn) hasNext
和 next
方法)束亏。
要實(shí)現(xiàn)可修改的 collection
,我們必須另外重寫此類的 add
方法(否則阵具,會(huì)拋出 UnsupportedOperationException
)碍遍,iterator
方法返回的迭代器還必須另外實(shí)現(xiàn)其 remove
方法。
AbstractList類
其定義如下:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
AbstractList
類是一個(gè)抽象類阳液,繼承了AbstractCollection
類怕敬,并實(shí)現(xiàn)了List接口,提供了 List 接口的大部分實(shí)現(xiàn)帘皿,對(duì)于連續(xù)的訪問(wèn)數(shù)據(jù)(如鏈表)东跪,應(yīng)優(yōu)先繼承 AbstractSequentialList
,而不是此類。
要實(shí)現(xiàn)不可修改的列表虽填,我們只需擴(kuò)展此類丁恭,并提供 get(int)
和 size()
方法的實(shí)現(xiàn)。
要實(shí)現(xiàn)可修改的列表斋日,我們必須另外重寫 set(int, E)
方法(否則將拋出 UnsupportedOperationException
)牲览。如果列表為可變大小,則也要重寫 add(int, E)
和 remove(int)
方法恶守。
AbstractSet類
其定義如下:
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}
AbstractSet
類是一個(gè)抽象類竭恬,繼承了AbstractCollection
類,并實(shí)現(xiàn)了Set接口熬的,提供了 Set 接口的大部分實(shí)現(xiàn)。
工具類及其它接口
ListIterator接口
其定義如下:
public interface ListIterator<E> extends Iterator<E> {}
ListIterator
接口繼承于Iterator
接口赊级,專門用于各種List類型的訪問(wèn)押框,其方法摘要如下圖所示:
從上圖可以看到,ListIterator
接口提供了前向/后向遍歷的方法理逊,同時(shí)也提供了add()
方法橡伞,用于添加元素,ListIterator
還可以通過(guò)nextIndex()
和previousIndex()
定位當(dāng)前索引位置晋被。
Arrays
此類包含用來(lái)操作數(shù)組(比如排序和搜索)的各種方法兑徘。主要方法有:
static <T> List<T> asList(T... a) // 返回一個(gè)受指定數(shù)組支持的固定大小的列表。
static int binarySearch(...) // 二分查找,數(shù)組需要有序
static void sort(...) // 排序
copyOf(...) // 復(fù)制數(shù)組
copyOfRange(...) // 復(fù)制部分?jǐn)?shù)組
Collections
此類完全由在 collection
上進(jìn)行操作或返回 collection
的靜態(tài)方法組成羡洛。主要方法有:
static <T> int binarySearch(...) // 二分查找
sort(...) // 對(duì)list集合排序
max(...) / min(...) // 對(duì)集合取最大值/最小值
static void reverse(List<?> list) // 反轉(zhuǎn)指定列表中元素的順序挂脑。
static void swap(List<?> list, int i, int j) // 在指定列表的指定位置處交換元素。
....
Arrays和Collections工具類的具體API可以參考JDK文檔欲侮,此處只列出了一小部分