Java集合系列01之概覽

系列文章

前言

從本篇開始阿迈,我將開始Java集合系列的梳理缴饭,本文先對(duì)集合框架中涉及到的接口,架構(gòu)绍哎,類等做一個(gè)總體展示瘟芝,后面的文章中再結(jié)合源碼分別剖析具體集合,希望能用兩個(gè)月的時(shí)間完成Java集合系列文章轧房。

Java最初版本只為最常用的數(shù)據(jù)結(jié)構(gòu)提供了很少的一組類:Vector纸颜,StackHashtable怀读,BitSetEnumeration接口诉位。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)成了集合類的框架捷沸,包含了大量的接口,抽象類狐史,框架圖如下所示:

集合框架.png

從上圖可以發(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主要包含了集合的基本操作和屬性薪伏,有兩大分支ListSet。其中定義了很多方法供其子類實(shí)現(xiàn)碴开,以實(shí)現(xiàn)數(shù)據(jù)操作毅该,方法列表如下圖所示:

Collection方法摘要.png

從方法列表中可以看出,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)類有HashSetTreeSet,而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)棚愤,其方法摘要如下圖所示:

Queue接口方法摘要.png

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ù)羊精。其方法摘要如下:

Map接口方法摘要.png

AbstractCollection類

其定義如下:

public abstract class AbstractCollection<E> extends Object implements Collection<E> {}

AbstractCollection類是一個(gè)抽象類斯够,提供了 Collection 接口的大部分實(shí)現(xiàn),以最大限度地減少了實(shí)現(xiàn)此接口所需的工作喧锦,除了iteratorsize 方法读规。

要實(shí)現(xiàn)一個(gè)不可修改的 collection,我們只需擴(kuò)展此類燃少,并實(shí)現(xiàn) iteratorsize 方法(iterator 方法返回的迭代器必須實(shí)現(xiàn) hasNextnext 方法)束亏。

要實(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接口方法摘要.png

從上圖可以看到,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文檔欲侮,此處只列出了一小部分

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市威蕉,隨后出現(xiàn)的幾起案子刁俭,更是在濱河造成了極大的恐慌,老刑警劉巖韧涨,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牍戚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡虑粥,警方通過(guò)查閱死者的電腦和手機(jī)如孝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)舀奶,“玉大人暑竟,你說(shuō)我怎么就攤上這事。” “怎么了但荤?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵罗岖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我腹躁,道長(zhǎng)桑包,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任纺非,我火速辦了婚禮哑了,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烧颖。我一直安慰自己弱左,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布炕淮。 她就那樣靜靜地躺著拆火,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涂圆。 梳的紋絲不亂的頭發(fā)上们镜,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音润歉,去河邊找鬼模狭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛踩衩,可吹牛的內(nèi)容都是我干的嚼鹉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼驱富,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼反砌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起萌朱,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宴树,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后晶疼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酒贬,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年翠霍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锭吨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寒匙,死狀恐怖零如,靈堂內(nèi)的尸體忽然破棺而出躏将,到底是詐尸還是另有隱情,我是刑警寧澤考蕾,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布祸憋,位于F島的核電站,受9級(jí)特大地震影響肖卧,放射性物質(zhì)發(fā)生泄漏蚯窥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一塞帐、第九天 我趴在偏房一處隱蔽的房頂上張望拦赠。 院中可真熱鬧,春花似錦葵姥、人聲如沸荷鼠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)颊咬。三九已至,卻和暖如春牡辽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敞临。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工态辛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挺尿。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓奏黑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親编矾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熟史,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359