Java開篇四:java的集合框架
集合框架被設(shè)計成要滿足以下幾個目標(biāo)。
? ? ? ? ? ? ? ? ? ? ??

該框架必須是高性能的?;炯希▌討B(tài)數(shù)組,鏈表,樹,哈希表)的實現(xiàn)也必須是高效的。
該框架允許不同類型的集合,以類似的方式工作,具有高度的互操作性。
對一個集合的擴(kuò)展和適應(yīng)必須是簡單的。

容器
容器:
容器,就是可以容納其他java對象的對象。java Collection Framwork(JCF) 為java開發(fā)者提供了通用的容器,其始于jdk1.2,優(yōu)點是:
降低編程難度
提高程序性能
提高API間的互操作性
降低學(xué)習(xí)難度
降低設(shè)計和實現(xiàn)相關(guān)API的難度
增加程序的重用性
Java容器里只能放對象,對于基本類型(int, long, float, double等),需要將其包裝成對象類型后(Integer, Long, Float, Double等)才能放到容器里。很多時候拆包裝和解包裝能夠自動完成。這雖然會導(dǎo)致額外的性能和空間開銷,但簡化了設(shè)計和編程。

泛型
泛型(Generics)
Java容器能夠容納任何類型的對象,這一點表面上是通過泛型機(jī)制完成,Java泛型不是什么神奇的東西,只是編譯器為我們提供的一個“語法糖”,泛型本身并不需要Java虛擬機(jī)的支持,只需要在編譯階段做一下簡單的字符串替換即可。實質(zhì)上Java的單繼承機(jī)制才是保證這一特性的根本,因為所有的對象都是Object的子類,容器里只要能夠存放Object對象就行了。事實上,所有容器的內(nèi)部存放的都是Object對象,泛型機(jī)制只是簡化了編程,由編譯器自動幫我們完成了強(qiáng)制類型轉(zhuǎn)換而已。JDK 1.4以及之前版本不支持泛型,類型轉(zhuǎn)換需要程序員顯式完成。
//JDK 1.4 or before
ArrayList list = new ArrayList();
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
for(int i = 0; i < list.size(); i++){
? ?String weekday = (String)list.get(i);//顯式類型轉(zhuǎn)換
? ?System.out.println(weekday.toUpperCase());
}
//JDK 1.5 or latter
ArrayList<String> list = new ArrayList<String>();//參數(shù)化類型
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
for(int i = 0; i < list.size(); i++){
? ?String weekday = list.get(i);//隱式類型轉(zhuǎn)換,編譯器自動完成
? ?System.out.println(weekday.toUpperCase());
}
內(nèi)存管理
跟C++復(fù)雜的內(nèi)存管理機(jī)制不同,Java GC自動包攬了一切,Java程序并不需要處理令人頭疼的內(nèi)存問題,因此JCF并不像C++ STL那樣需要專門的空間適配器(alloctor)。另外,由于Java里對象都在堆上,且對象只能通過引用(reference,跟C++中的引用不是同一個概念,可以理解成經(jīng)過包裝后的指針)訪問,容器里放的其實是對象的引用而不是對象本身,也就不存在C++容器的復(fù)制拷貝問題。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


集合
什么是集合(Collection)?集合就是“由若干個確定的元素所構(gòu)成的整體”。
在數(shù)學(xué)中,我們經(jīng)常遇到集合的概念。例如:
有限集合:
一個班所有的同學(xué)構(gòu)成的集合;
一個網(wǎng)站所有的商品構(gòu)成的集合;
...
無限集合:
全體自然數(shù)集合:1,2,3,……
有理數(shù)集合;
實數(shù)集合;
...
為什么要在計算機(jī)中引入集合呢?這是為了便于處理一組類似的數(shù)據(jù),例如:
計算所有同學(xué)的總成績和平均成績;
列舉所有的商品名稱和價格;
……
為此,整個集合框架就圍繞一組標(biāo)準(zhǔn)接口而設(shè)計。你可以直接使用這些接口的標(biāo)準(zhǔn)實現(xiàn),諸如:LinkedList,?HashSet, 和?TreeSet?等,除此之外你也可以通過這些接口實現(xiàn)自己的集合。

從上面的集合框架圖可以看到,Java 集合框架主要包括兩種類型的容器,一種是集合(Collection),存儲一個元素集合,另一種是圖(Map),存儲鍵/值對映射。Collection 接口又有 3 種子類型,List、Set 和 Queue,再下面是一些抽象類,最后是具體實現(xiàn)類,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。
02
集合框架-2

集合框架是一個用來代表和操縱集合的統(tǒng)一架構(gòu)。所有的集合框架都包含如下內(nèi)容:
接口:是代表集合的抽象數(shù)據(jù)類型。例如 Collection、List、Set、Map 等。之所以定義多個接口,是為了以不同的方式操作集合對象
實現(xiàn)(類):是集合接口的具體實現(xiàn)。從本質(zhì)上講,它們是可重復(fù)使用的數(shù)據(jù)結(jié)構(gòu),例如:ArrayList、LinkedList、HashSet、HashMap。
算法:是實現(xiàn)集合接口的對象里的方法執(zhí)行的一些有用的計算,例如:搜索和排序。這些算法被稱為多態(tài),那是因為相同的方法可以在相似的接口上有著不同的實現(xiàn)。
除了集合,該框架也定義了幾個 Map 接口和類。Map 里存儲的是鍵/值對。盡管 Map 不是集合,但是它們完全整合在集合中。
在Java中,如果一個Java對象可以在內(nèi)部持有若干其他Java對象,并對外提供訪問接口,我們把這種Java對象稱為集合。很顯然,Java的數(shù)組可以看作是一種集合:
String[] ss = new String[10]; // 可以持有10個String對象
ss[0] = "Hello"; // 可以放入String對象
String first = ss[0]; // 可以獲取String對象
既然Java提供了數(shù)組這種數(shù)據(jù)類型,可以充當(dāng)集合,那么,我們?yōu)槭裁催€需要其他集合類?這是因為數(shù)組有如下限制:
在Java中,如果一個Java對象可以在內(nèi)部持有若干其他Java對象,并對外提供訪問接口,我們把這種Java對象稱為集合。很顯然,Java的數(shù)組可以看作是一種集合:
String[] ss = new String[10]; // 可以持有10個String對象
ss[0] = "Hello"; // 可以放入String對象
String first = ss[0]; // 可以獲取String對象
既然Java提供了數(shù)組這種數(shù)據(jù)類型,可以充當(dāng)集合,那么,我們?yōu)槭裁催€需要其他集合類?這是因為數(shù)組有如下限制:
數(shù)組初始化后大小不可變;
數(shù)組只能按索引順序存取。
因此,我們需要各種不同類型的集合類來處理不同的數(shù)據(jù),例如:
可變大小的順序鏈表;
保證無重復(fù)元素的集合;
...
03
集合框架-3
Collection:
Java標(biāo)準(zhǔn)庫自帶的java.util
包提供了集合類:Collection
,它是除Map
外所有其他集合類的根接口。Java的java.util
包主要提供了以下三種類型的集合:
List
:一種有序列表的集合,例如,按索引排列的Student
的List
;Set
:一種保證沒有重復(fù)元素的集合,例如,所有無重復(fù)名稱的Student
的Set
;Map
:一種通過鍵值(key-value)查找的映射表集合,例如,根據(jù)Student
的name
查找對應(yīng)Student
的Map
。
Java集合的設(shè)計有幾個特點:一是實現(xiàn)了接口和實現(xiàn)類相分離,例如,有序表的接口是List
,具體的實現(xiàn)類有ArrayList
,LinkedList
等,二是支持泛型,我們可以限制在一個集合中只能放入同一種數(shù)據(jù)類型的元素,例如:
List<String> list = new ArrayList<>(); // 只能放入String類型
最后,Java訪問集合總是通過統(tǒng)一的方式——迭代器(Iterator)來實現(xiàn),它最明顯的好處在于無需知道集合內(nèi)部元素是按什么方式存儲的。
由于Java的集合設(shè)計非常久遠(yuǎn),中間經(jīng)歷過大規(guī)模改進(jìn),我們要注意到有一小部分集合類是遺留類,不應(yīng)該繼續(xù)使用:
Hashtable
:一種線程安全的Map
實現(xiàn);Vector
:一種線程安全的List
實現(xiàn);Stack
:基于Vector
實現(xiàn)的LIFO
的棧。
還有一小部分接口是遺留接口,也不應(yīng)該繼續(xù)使用:
Enumeration<E>
:已被Iterator<E>
取代。
總結(jié):
Java的集合類定義在java.util
包中,支持泛型,主要提供了3種集合類,包括List
,Set
和Map
。Java集合使用統(tǒng)一的Iterator
遍歷,盡量不要使用遺留接口。
下一篇:我們來介紹集合的List
? ? ??? ? ? ? ? ? ? ? ??
