
如果一個程序只包含固定數(shù)量的且生命周期都是已知的對象,那么這是一個非常簡單的程序。
11.1泛型和類型安全容器
使用泛型可以在編譯期防止錯誤類型放到容器里,使其變成一個編譯期錯誤,而不是運行時錯誤。
11.2 基本概念
Java容器的用途是保存對象,劃分為兩個不同的概念
- 1 Collection 一個獨立元素的序列,這些元素都服從一條或多條的規(guī)則。List必須按照插入的順序保存元素,而Set不能有重復(fù)元素。Queue按照隊列規(guī)則來確定對象產(chǎn)生的順序
- 2 Map一組成對的鍵值對對象,允許你使用鍵來查找值。ArrayList允許你使用索引來查找值。
11.4 容器的打印
使用Arrays.toString()來產(chǎn)生數(shù)組的可打印表示。
11.5 List
LIst接口在Collection的基礎(chǔ)上添加大量的方法,是的可以在List的中間插入和移除元素
11.6 迭代器
容器必須有某種方法可以插入元素并在此取回,為了以通用性代碼實現(xiàn)這一點,迭代器的概念就可以達到此目的。它的工作是遍歷并選擇序列中的對象。Java的Iterator只能單向移動,這個Iterator只能用來
- 1) 使用Iterator()要求返回一個Iterator.
- 使用next()獲取序列中的下一個元素。
- 3) 使用hasNext()檢查序列中是否還有元素
- 4)使用remove()將迭代器元素刪除
迭代器統(tǒng)一了對容器的訪問方式
ListIterator是一個更加強大的Iterator的子類,它只能用于各種List類的訪問。盡管Iterator只能向前移動,但是ListIterator可以雙向移動。它還可以產(chǎn)生對于迭代器在列表中指向的當(dāng)前位置的前一個和后一個元素的索引,并且可以使用set()方法替換它訪問過的最后一個元素。你可以通過調(diào)用listIterator()方法產(chǎn)生一個指向List開始處的ListIterator,并且可以通過調(diào)用listIterator(n)方法創(chuàng)建一個一開始就指向類表索引為n的元素處的ListIterator。
11.7 LinkedList
LinkedList實現(xiàn)基本接口List,在List中間插入和移除時比ArrayList更高效,在隨機訪問方面要遜色一些。
LinkedList還添加了可以使用其用作棧、隊列或雙端隊列的方法
11.8 Stack
通常指先進后出的容器
LinkList具有能夠直接實現(xiàn)棧的所有功能和方法,可以直接將LinkList作為棧使用。
11.9 Set
不保存相同的元素。容易詢問某個對象是否在某個Set中,查找成為了Set中最重要的操作。通常會選擇HashSet的實現(xiàn),它對快速查找進行了優(yōu)化。
Set具有與Collection完全一樣的接口,因此沒有額外的功能,實際上Set就是Collection,只是行為不同(這是繼承與多態(tài)思想的典型應(yīng)用:表現(xiàn)不同的行為)
11.10 Map
Map接口中鍵和值一一映射. 可以通過鍵來獲取值。
給定一個鍵和一個值,你可以將該值存儲在一個Map對象. 之后,你可以通過鍵來訪問對應(yīng)的值。
當(dāng)訪問的值不存在的時候,方法就會拋出一個NoSuchElementException異常.
當(dāng)對象的類型和Map里元素類型不兼容的時候,就會拋出一個 ClassCastException異常。
當(dāng)在不允許使用Null對象的Map中使用Null對象,會拋出一個NullPointerException 異常。
當(dāng)嘗試修改一個只讀的Map時,會拋出一個UnsupportedOperationException異常。
11.11 Queue
隊列是一個典型的先進先出的容器。即從容器的一段放入,從另一端取出,放入的順序和取出的順序相同。隊列被當(dāng)做一種可靠的將對象從程序的某個區(qū)域傳輸?shù)搅硪粋€區(qū)域的途徑。隊列在并發(fā)編程中特別重要 因為他們可以安全地將對象從一個容物傳輸給另一個任務(wù)。
LinkedList提供方法支持隊列的行為,并且它實現(xiàn)了Queue的接口,因此LinkList可以用作Queue的一種實現(xiàn)。通過將LinkedList向上轉(zhuǎn)型為Queue
11.12 Collection
Collection是描述所有容器共性的根接口,它可能會被認(rèn)為是一個“附屬接口”,即因為要表示其他若干個接口的共性而出現(xiàn)的接口。
11.13 Foreach與迭代器
foreach語法主要用于數(shù)組,它可以應(yīng)用于任何Collection對象。
public class ForEachCollections
public static void main(String[] args){
Collection<String> cs = new LinkedList<String>();
Collection.addAll(cs,"Take the long way home".split(" "));
for(String s : cs){
System.out.print("'"+s+ "'")
}
}
}
//log
'Tage' 'the' 'log' 'way' 'home'
由于cs是一個Collection,所以這段代碼展示了能夠與foreach一起工作是所有Collection對象的特性。
之所以能夠工作,是因為Java SE5引入了新的被稱為Iterable的接口,該接口包含一個能夠產(chǎn)生Iterator的iterator()方法,并且Iterable接口被foreach用來在序列中移動。因此如果你創(chuàng)建了任何Iterable的類,都可以將它用于foreach語句中。
11.14 總結(jié)
Java提供大量的持有對象方式:
- 1 數(shù)組講對象聯(lián)系起來。容量一旦生成就不能改變。
- 2 Collection保存單一元素,Map保存相關(guān)聯(lián)的鍵值對。Collection和各種Map都可以在你向其中添加更多元素時,自動調(diào)整尺寸。容器不能持有基本類型,但是自動包裝機制會仔細(xì)的執(zhí)行基本類型到容器中所持有的包裝器類型之間的雙向轉(zhuǎn)換。
- 3 像數(shù)組一樣,List也建立數(shù)字索引和對象的關(guān)系,數(shù)組和List都是排好序的容器。List能夠自動擴充容量。
- 4 如果要進行大量的隨機訪問,就使用ArrayList;如果要經(jīng)常從表中插入和刪除元素,則應(yīng)該使用LinkedList.
- 5 各種Queue以及棧的行為,由LinkedList提供支持。
- 6 Map是一種將對象(而非數(shù)字)與對象相關(guān)聯(lián)的設(shè)計,HashMap設(shè)計用來快速訪問;而TreeMap保持“鍵”始終處于排序狀態(tài),所以沒有HashMap快。LinkedHashMap保持元素插入的順序,但是也通過散列提供快速訪問的能力。
- 7 Set不接受重復(fù)元素。HashSet提供最快的查詢速度,而TreeSet保持元素處于排序狀態(tài)。LinkListHashSet以插入順序保持元素。
-
8 新程序中不應(yīng)該使用過時的Vector、HastTable和Stack
簡單的容器分類
有四種容器:Map、List、Set、Queue,(Queue的Java.util.concurrent實現(xiàn)沒有包括這張圖)。常用的容器用黑色粗框表示。
