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