java集合——集合接口+迭代器接口
【0】README
0.1) 本文描述轉(zhuǎn)自 core java volume 1, 源代碼 diy 的, 旨在理解 java集合框架——集合接口+迭代器接口 的相關(guān)知識(shí);
0.2) for full source code , please visit https://github.com/pacosonTang/core-java-volume/tree/master/chapter13
【1】將集合的接口與實(shí)現(xiàn)分離
1.1)java集合類庫(kù)將 接口與實(shí)現(xiàn)分離。 我們看一下, 隊(duì)列是如何分離的;
1.2)隊(duì)列接口指出可以再隊(duì)列的尾部添加元素, 在隊(duì)列的頭部刪除元素, 并可以查找隊(duì)列中元素的個(gè)數(shù);
- 1.2.1)一個(gè)隊(duì)列接口的最小形式類似下面這樣:
- 1.2.2)隊(duì)列通常有兩種實(shí)現(xiàn)方式: 一種是使用循環(huán)數(shù)組, 另一種是使用鏈表;
- 1.2.3)每一個(gè)實(shí)現(xiàn)都可以通過(guò)一個(gè)實(shí)現(xiàn)了 Queue接口的類表示:
Annotation)
- A1)如果需要使用循環(huán)數(shù)組隊(duì)列: 可以使用 ArrayDeque 類;
- A2)如果需要使用 一個(gè)鏈表隊(duì)列: 就直接使用 LinkedList 類, 這個(gè)類實(shí)現(xiàn)了 Queue接口;
1.3)使用接口類型存放集合的引用:
Queue<Customer> expressLane = new CircularArrayQueue<>(100); expressLane.add(new Customer("Harry"));- 1.3.1)只需要對(duì)程序的一個(gè)地方做出修改,即調(diào)用構(gòu)造器的地方, 如果覺(jué)得LinkedListQueue是個(gè)更好的選擇,將代碼修改為:
- 1.3.2)因?yàn)檠h(huán)數(shù)組要比鏈表效率高,因此多數(shù)人優(yōu)先選擇循環(huán)數(shù)組;循環(huán)數(shù)組是一個(gè)有界集合, 即容量有限。如果程序中要收集的對(duì)象數(shù)量沒(méi)有上限, 就最好使用鏈表來(lái)實(shí)現(xiàn);
- 1.3.3)在研究API文檔時(shí),發(fā)現(xiàn)另外一組名字為 Abstract開頭的類: 如, AbstractQueue, 這些類是為類庫(kù)實(shí)現(xiàn)者而設(shè)計(jì)的, 如果想要實(shí)現(xiàn)自己的隊(duì)列類,會(huì)發(fā)現(xiàn)擴(kuò)展AbstractQueue類要比實(shí)現(xiàn)Queue接口中的所有方法要輕松得多;
【2】java類庫(kù)中的集合接口和迭代器接口
2.1)在java類庫(kù)中, 集合類的基本接口是 Collection 接口,有兩個(gè)基本方法:
public interface Collection<E> {boolean add(E element); Iterator<E> iterator(); }對(duì)上述代碼的分析(Analysis):
- A1)add方法: 用于向集合添加元素,如果添加元素確實(shí)改變了集合就返回ture, 否則返回false;如,如果試圖向集合中添加一個(gè)對(duì)象, 而這個(gè)對(duì)象在集合中已經(jīng)存在, 這個(gè)添加請(qǐng)求就沒(méi)有實(shí)效了,因?yàn)榧现胁辉试S有重復(fù)的對(duì)象;
- A2)iterator方法:該方法用于返回一個(gè)實(shí)現(xiàn)了 Iterator接口的對(duì)象 。 可以使用這個(gè)迭代器對(duì)象依次訪問(wèn)集合中的元素:
2.2)迭代器, Iterator接口包含3個(gè)方法:
public interface Iterator<E> {E next();boolean hasNext();void remove(); }- 2.2.1)通過(guò)反復(fù)調(diào)用 next方法, 可以逐個(gè)訪問(wèn)集合中的每個(gè)元素。但是, 如果達(dá)到了集合的末尾,next方法將拋出一個(gè) NoSuchElementException;因此,需要在 next之前調(diào)用 hasNext方法;
- 2.2.2)看個(gè)荔枝:
Attention)從Java SE 5.0 后, 可以使用for each循環(huán)表示上述操作:
for(String elements : c) {do sth with element }
對(duì)上述代碼的分析(Analysis):
- A1)編譯器將簡(jiǎn)單地將 “for each”循環(huán)翻譯為 帶有迭代器的循環(huán);
- A2)for each循環(huán)可以與任何實(shí)現(xiàn)了 Iterator接口的對(duì)象一起工作,這個(gè)接口只包含一個(gè)方法:
Attention)Collection接口擴(kuò)展了 Iterable 接口, 因此, 對(duì)于標(biāo)準(zhǔn)類庫(kù)中的任何集合都可以使用 for each;
2.2.3)元素被訪問(wèn)的順序取決于集合類型
- 2.2.3.1)如果對(duì) ArrayList進(jìn)行迭代, 迭代器將從索引0開始;
- 2.2.3.2)如果訪問(wèn) HashSet中的元素, 每個(gè)元素將會(huì)按照某種隨機(jī)的次序出現(xiàn);雖然可以確定在迭代過(guò)程中能夠遍歷到集合中的所有元素, 但卻無(wú)法預(yù)知元素被訪問(wèn)的順序;
Annotation)編程老手會(huì)注意到: Iterator接口的next 和 hasNext方法 與 Enumeration 接口的nextElement 和 hasMoreElements 方法的作用一樣。 java集合類庫(kù)的設(shè)計(jì)者可以選擇使用Enumeration接口。但是, 它們不喜歡這個(gè)接口累贅的方法名, 于是引入了較短的方法名的新接口;
2.2.4)java迭代器:應(yīng)該將java迭代器認(rèn)為是位于 兩個(gè)元素之間, 當(dāng)調(diào)用next 方法時(shí), 迭代器就越過(guò)下一個(gè)元素, 并返回剛剛越過(guò)的那個(gè)元素的引用;
Annotation)有用的類推:可以將Iterator.next 和 InputStream.read 看做是等效的。從數(shù)據(jù)流中讀取一個(gè)字節(jié), 就會(huì)自動(dòng)地消耗掉這個(gè)字節(jié)。下一次調(diào)用read將會(huì)消耗并返回輸入的下一個(gè)字節(jié)。用同樣的方式, 反復(fù)地調(diào)用next 就可以讀取集合中所有元素了;
2.3)刪除元素
- 2.3.1)Iterator的remove方法 將會(huì)刪除上次調(diào)用next方法時(shí)返回的 元素。在大多數(shù)情況下,在決定刪除某個(gè)元素前應(yīng)該先看一下這個(gè)元素是很具有實(shí)際意義的。然而, 如果想要?jiǎng)h除指定位置上的元素, 仍然需要越過(guò)這個(gè)元素。
- 2.3.2)看個(gè)荔枝(如何刪除集合中第一個(gè)元素):
- 你要記住, 要?jiǎng)h除某個(gè)元素, 你得要先越過(guò)這個(gè)元素;
- 2.3.3)對(duì)next方法 和 remove方法的調(diào)用具有相互依賴性。 如果調(diào)用 remove 之前沒(méi)有調(diào)用next 將是不合法的。 如果這樣做, 會(huì)拋出一個(gè) IllegalStateException 異常;
- 2.3.4)看個(gè)荔枝: 如果想刪除兩個(gè)相鄰元素, 不能直接這樣調(diào)用:
2.4)泛型使用方法
* 2.4.1)由于Collection 和 Iterator 都是泛型接口,可以編寫操作任何集合類型的實(shí)用方法。看個(gè)荔枝:下面是一個(gè)檢測(cè)任意寄賀卡是否包含指定元素的泛型方法:
- 2.4.2)事實(shí)上, Collection接口聲明了很多有用的方法, 所有的實(shí)現(xiàn)類都必須提供這些方法, 下面列舉了部分:
- 2.4.3)AbstractCollection:當(dāng)然, 如果實(shí)現(xiàn) Collection接口的每個(gè)類都要提供如此多的例行方法是一件很煩人的事情。為了能夠讓實(shí)現(xiàn)者更容易地實(shí)現(xiàn)這個(gè)接口,java類庫(kù)提供了一個(gè) 類 AbstractCollection , 它將基礎(chǔ)方法 size 和 iterator 抽象化了;
(我的理解為: 抽象類AbstractCollection實(shí)現(xiàn)部分的例行方法, 其他可變的方法交給用戶去實(shí)現(xiàn))
對(duì)以上代碼的分析(Analysis):
- A1)一個(gè)具體集合類可以擴(kuò)展 AbstractCollection類了;
- A2)現(xiàn)在要由具體的集合類提供 iterator 方法, 而 contains 方法已由 AbstractCollection超類提供了;
總結(jié)
以上是生活随笔為你收集整理的java集合——集合接口+迭代器接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java集合框架——接口图+类图+遗留类
- 下一篇: java集合—— 链表(java中的所有