關於Java容器類學習心得體會

來源:果殼範文吧 9.41K

由於小編對C++比較熟悉,所以學習Java應該重點體會Java帶來的新概念。本文基本上是Java標準庫中集合框架的基本概念,沒有例子。寫本文的目的在於方便小編很長時間後若是忘了這些東西可以通過這片文章迅速回憶起來。

關於Java容器類學習心得體會

1. 介面

整個Java容器類的基礎是容器介面(例如Collection,Map等介面),而不是類。使用介面的最大好處在於將容器的實現與容器的介面分開,這就意味著你可以使用相同的方法訪問容器而不用關心容器是由什麼樣的資料結構實現的。同樣,Iterator介面也使得使用者可以使用相同的方法訪問不同的容器類。以上這些是通用演算法的基礎。China

1.1 Collection介面

Collection介面有如下基本方法:

boolean add(Object obj):如果新增物件後,集合確實發生了變化,則返回true;否則返回false

Iterator iterator():返回一個實現了Iterator介面的物件

此外,還有

int size(),boolean isEmpty(),boolean contains(Object obj),void clear()等許多有用的方法

1.2 Map介面

Map用於存放關鍵字/值對。有如下基本方法:

Object get(Object key)

Object put(Object key,Object balue)

Set keySet()

Set entrySet()

此外,還有其他有用的方法。

需要注意的是,從表面看它似乎就是一種由鍵值對構成的集合,但實際上並不是這樣。不過另一方面假如將Map的某一部分看作集合,有時候也還是顯得非常方便的。換言之你可以建立一個集合用它來表達Map的那一部分。綜上所述,一個Map可以返回的東西包括它的鍵值構成的一個Set、由它的值構成的一個集合或者由它的鍵值對構成的一個Set。

1.3 Iterator介面

Iterator介面有下面3個基本方法:

Object next():返回迭代器剛越過的元素的引用

boolean hasNext():判斷容器內是否還有可供訪問的元素

void remove():刪除迭代器剛越過的元素

注意:Java中的迭代器與STL中的迭代器在概念上有很重要的區別。在STL中,迭代器類似於陣列的索引,使用這種迭代器可以檢視存放在該位置上的.元素(類似於通過陣列索引i來訪問c[i]一樣)。Java中的迭代器並不這樣執行。檢視與位置的變化緊密的結合在一起。每次通過next()訪問一個元素的同時,迭代器的位置會自動向前走一步。

這個問題可以這樣理解:Java中的迭代器指向的位置並不是元素,而是元素之間。這樣,每次呼叫next()時,迭代器便越過下一個元素,同時返回它剛越過的那個元素的引用。

根據上面的說明,很容易得出下面的程式碼是錯誤的:

ve();

ve();

而下面的程式碼是正確的:

ve();

();

ve();

迭代器的典型應用

Iterator it=ator();

while(ext())

{

Object obj=();

//do something with obj

}

1.4 子介面

1.4.1 List介面

List從Collection介面中分立出來是因為List的特點——有序的集合。這裡指的有序並不是按照大小排好序的(Sorted),而是指集合是可以以確定的順序訪問的序列。針對List的這個特點,它比Collection介面增加了通過索引進行操作的方法。例如,add、remove、get、set等方法的引數表中都可以加入索引的數值,從而操作處在索引位置處的元素。

1.4.2 Set介面

Set與List的不同,它裡面的元素是無序的;所以,不能通過任何索引的方法來操作Set物件China It Power . ComZKWED

1.4.3 ListIterator介面

使用與List的迭代器,比Iterator介面增加了一些方法(例如add()等)。此外,由於List是雙向表,所以還增加了Object previous()和boolean hasPrevious()方法,用法與next()和hasNext()一樣。China It Power . ComZKWED

1.4.4 SortedMap介面

包含如下基本方法:

Comparator comparator()

Object firstKey()

Object lastKey()China It Power . ComZKWED

2. 抽象容器類

2.1 抽象容器類包括AbstractCollection,AbstractList,AbstractSet等等China It Power . ComZKWED

2.2 為什麼要有抽象結合類?

例如Collection介面中定義了許多有用的方法,如果實現Collection介面的每個類都自行實現這麼多的方法,那將是非常麻煩的。為了使實現Collection介面的類的實現更容易,AbstractCollection類讓一些基本方法(比如add()和iterator())變成了抽象的方法,而利用這些基本方法的其他方法(例如addAll()等等)則具體實現了。China It Power . ComZKWED

3. 具體的容器

3.1 ArrayList與LinkedList

都是實現了List介面的類,是有序集。List介面支援通過索引的方法來訪問元素,對於這一點,ArrayList沒有任何問題;但是對於LinkedList則有很大的問題,連結串列本身不應該支援隨機儲存,但是作為List的一個實現,連結串列也提供了對隨機訪問的支援,但是效率很低。每次通過索引的方法都是進行一次遍歷。我認為,其實就不應該讓連結串列支援隨機訪問;而Java這樣實現我想是因為整個集合框架的體系,使得連結串列與陣列可以使用同樣的方法使用。綜上所述,對於LinkedList最好不使用隨機訪問,而使用迭代器。China It Power . ComZKWED

3.2 TreeSet

3.2.1 TreeSet是SortedSet的一個實現。根據資料結構的知識可以知道,樹的效率非常高,而且Java標準庫中有TreeSet這樣的類,以後應該儘量使用TreeSet來提高程式的效率。

3.2.2 需要注意的是:TreeSet作為有序集,它通過compareTo或者Comparator來將集合元素排序。任何具有相同比較值的元素(無論它們是否equals()),在TreeSet中都作為同一個元素,從而不能有重複。這樣以來,即使是不同的物件也不能加入到集合中,這一點有時候很不方便。我在編寫A*演算法時,不同狀態有時候對應著同一個啟發函式值,那麼這些不同的狀態就無法加入到TreeSet中。China It Power . ComZKWED

3.3 HashSet

3.3.1 HashSet是非常高效的資料結構,與TreeSet不同,HashSet是比較物件的equals()方法來區分不同的物件。這樣只有真正不同的物件才能不被重複的加入到集合中。

3.3.2 需要注意的是:HashSet效率非常高,但是物件的hashCode函式不好確定。一般預設的物件的hashCode函式是根據物件的記憶體地址得到的。好的hashCode函式是HashSet成功運用的關鍵。China It Power . ComZKWED

4. 檢視

4.1 什麼是檢視?

對映象類使用keySet()方法,彷彿該方法建立了一個新的集合,並將影響的所有關鍵字都填入這個集合。實際情況並非如此,對這個集合的任何操作都將反映到原始的映象物件上。

實際上,keySet()返回的是一個實現Set介面的物件,對該物件的操作就是對映象的操作。這樣的集合成為檢視。

4.2 檢視的應用

4.2.1 將現有的容器變為執行緒安全的容器:使用hronizedCollection(Collection c)方法,在SDK文件中該方法的解釋是“Returns a synchronized (thread-safe) collection backed by the specified collection”。

4.2.2 將現有的容器變為只讀的容器:使用difiableCollection(Collection c)方法,在SDK文件中該方法的解釋是“Returns an unmodifiable view of the specified collection.”。

4.2.3 子範圍

4.2.4 Arrays類中的asList()方法China It Power . ComZKWED

5. 通用演算法

通用的集合介面帶來的一大好處就是可以編寫通用演算法。可以使用Collections中的靜態通用方法,也可以編寫自己的通用方法。

(具體的演算法的內容在此略去)China It Power . ComZKWED

總結:千萬記住這句話——沒有最好的容器(資料結構),要根據不同的問題選擇不同的容器,以此來達到功能的要求和效率的最優。

熱門標籤