Map、Set、Iterator迭代詳解
Map接口定義了四種類(lèi)型的方法,每個(gè)Map都包含這些方法。
equals(Object o)比較指定對(duì)象與此Map的等價(jià)性。
hashCode()返回此Map的哈希碼。
Map定義了幾個(gè)用于插放和刪除元素的變換方法。
remove(Object key) 從Map中刪除鍵和關(guān)聯(lián)的值。
put(object key,Object value) 將指定值與指定鍵相關(guān)聯(lián)。
clear() 從Map雖刪除所有映射。
putAll(Map t) 將指定Map中的所有映射復(fù)制到此Map。
查看Map
迭代Map中的元素不存在直接了當(dāng)?shù)姆椒?。假如要查詢某個(gè)Map以了解其哪些元素滿足特定查詢或假如要迭代其所有元素,則您首先需要獲取該Map的“視圖”。有三種可能的視圖:所有
鍵值對(duì)、所有鍵、所有值。前兩個(gè)視圖均返回Set對(duì)象,第三個(gè)視圖返回Collection對(duì)象。就這兩種情況而言,問(wèn)題到這里并沒(méi)有結(jié)束,這是因?yàn)槟鸁o(wú)法直接迭代Collection對(duì)象或Set對(duì)
象。要進(jìn)行迭代,您必須獲得一個(gè)Iterator對(duì)象。因此要迭代Map的元素,必須進(jìn)行如下編碼:
Iterator keyValuePairs = aMap.entrySet().iterator();
Iterator keys=aMap.keySet().iterator();
Iterator values=aMap.values().iterator();
值得注意的是,這些對(duì)象實(shí)際上是基礎(chǔ)Map的視圖,而不是包含所有元素的副本。
使用Iterator對(duì)象,您可以遍歷Map的元素,還可以刪除Map中的元素。
EnterySet()返回Map中所包含映射的Set視圖。Set中的每個(gè)元素都是一個(gè)Map.Entry對(duì)象,可以使用getKey()和getValue()方法訪問(wèn)后者的鍵元素和值元素。
keySet()返回Map中所包含鍵的Set視圖。刪除Set中的元素還將刪除Map中相應(yīng)原映射。
values()返回Map中所包含值的Collection視圖。刪除Collection中的元素還將刪除Map中相應(yīng)的映射
Map訪問(wèn)和測(cè)試方法:
get(Object key) 返回與指定鍵關(guān)聯(lián)的值
containsKey(Object key) 假如Map包含指定鍵的映射,則返回True
isEmpty() 假如Map不包含鍵-值映射,則返回True
size() 返回Map中的鍵值映射的數(shù)目。
Set(interface):存入Set的每個(gè)元素必須是唯一的,因?yàn)镾et不保存重復(fù)元素。加入Set的Object必須定義equals()方法以確保對(duì)象的唯一性。
Set與Collection有完全一樣的接口。Set接口不保證維護(hù)元素的次序。
迭代器是一種設(shè)計(jì)模式,它是一個(gè)對(duì)象,它可以遍歷并選擇序列中的對(duì)象,而開(kāi)人員不需要了解該序列的底層結(jié)構(gòu)。迭代器通常被稱為“輕量級(jí)”對(duì)象,因?yàn)閯?chuàng)建它的代價(jià)小。
Java中的Iterator功能比較簡(jiǎn)單,并且只能單向移動(dòng):使用方法iterator()要求容器返回一個(gè)Iterator。第一次調(diào)用Iterator的next()方法時(shí),它返回序列的第一個(gè)元素。使用next()獲得序列中的
下一個(gè)元素。使用hasNext()檢查序列中是否還有元素。使用remove()將迭代器新返回的元素刪除。
Java平臺(tái)的集合框架
“集合框架”主要由一組用來(lái)操作對(duì)象的接口組成。不同接口描述一組不同數(shù)據(jù)類(lèi)型。
集合接口:6個(gè)接口,表示不同集合類(lèi)型,是集合框架的基礎(chǔ)。
抽象類(lèi):5個(gè)抽象類(lèi),對(duì)集合接口的部分實(shí)現(xiàn)??蓴U(kuò)展為自定義集合類(lèi)。
實(shí)現(xiàn)類(lèi):8個(gè)實(shí)現(xiàn)類(lèi),對(duì)接口的具體實(shí)現(xiàn)。
在很大程度上,一旦您理解了接口,您就理解了框架。雖然您總要?jiǎng)?chuàng)建接口特定的實(shí)現(xiàn),但訪問(wèn)實(shí)際集合的方法應(yīng)該限制在接口方法的使用上;
因此,允許您更基本的數(shù)據(jù)結(jié)構(gòu)而不必改變其它代碼。
Collection接口是一組允許重復(fù)的對(duì)象。
Set接口繼承Collection,但不允許重復(fù),使用自己內(nèi)部的排列機(jī)制。
List接口繼承Collection,允許重復(fù),以元素安插的次序來(lái)放置元素,不會(huì)重新排列。
Map接口是一組成對(duì)的鍵-值對(duì)象。Map中不能有重復(fù)的Key.擁有自己的內(nèi)部排列機(jī)制。
容器中的元素類(lèi)型都為Object。從容器取得元素時(shí),必須把它轉(zhuǎn)換成原來(lái)的類(lèi)型。
集合接口:
Collection接口:用于表示任何對(duì)象或元素組。想要盡可能以常規(guī)方式處理一組元素時(shí),就使用這一接口。
1、單元素添加、刪除操作:
Boolean add(Object o):將對(duì)象添加到集合
Boolean remove (Object o):如果集體中有與O相匹配的對(duì)象,則刪除對(duì)象O。
2、查詢操作:
Int size():返回當(dāng)前集合中元素的數(shù)量
Boolean isEmpty():判斷集合中是否有任何元素。
Boolean contains(Object o):查找集合中是否否有對(duì)象O
Iterator iterator():返回一個(gè)迭代器,用來(lái)訪問(wèn)集合中的各個(gè)元素。
3、組操作:作用于元素組或整個(gè)集合
Boolean containsAll(Collection c):查找集合中是否含有集合C中所有元素
Boolean addAll(Collection c):將集合C中所有元素添加到該集合。
Void clear():刪除集合中所有元素。
Void removeAll(Collection c):從集合中刪除集合C中的所有元素。
Void retainAll(Collection c):從集合中刪除集合C中不包含的元素
4、Collection轉(zhuǎn)換為Object數(shù)組:
Object[] toArray():返回一個(gè)內(nèi)含集合所有元素的Array
Object[] toArray(Object[] a):返回一個(gè)內(nèi)含集合所有元素的Array.運(yùn)行期返回的Array和參數(shù)A的型別相同,需要轉(zhuǎn)換為正確型別。
此外,您還可以把集合轉(zhuǎn)換成其它任何其它的對(duì)象數(shù)組。但是,您不能直接把集合轉(zhuǎn)換成基本數(shù)據(jù)類(lèi)型的數(shù)組,因?yàn)榧媳仨毘钟袑?duì)象。Collection不提供get()方法。如果要遍歷
Collection中的元素,就必須用Iterator.
AbstractCollection抽象類(lèi)
AbstactCollection類(lèi)提供具體“集合框架”類(lèi)的基本功能。雖然您可以自實(shí)現(xiàn)Collection接口的所有方法,但是,除了Iterator()和Size()方法在恰當(dāng)?shù)淖宇?lèi)中實(shí)現(xiàn)以外,其它所有方法都由
AbstractCollection類(lèi)來(lái)提供實(shí)現(xiàn)。如果子類(lèi)不覆蓋某些方法,可選的方法將拋出異常。
Iterator接口
Collection接口的Iterator()方法返回一個(gè)Iterator。Iterator接口方法能以迭代方式逐個(gè)訪問(wèn)集合中各個(gè)元素,并安全的從Collection中除去適當(dāng)?shù)脑亍?/p>
1、Boolean hasNext():判斷是否存在另一個(gè)可訪問(wèn)的元素。
2、Object next():返回要訪問(wèn)的下一個(gè)元素。如果到達(dá)集合結(jié)尾,則拋出NoSuchElementException異常。
3、Void remove():刪除上次訪問(wèn)返回的對(duì)象。本方法必須緊跟在一個(gè)元素的訪問(wèn)后執(zhí)行。如果上次訪問(wèn)后集合已被修改,方法將拋出
IIIegalStateException。
Iterator中刪除操作對(duì)底層Collection也有影響。
迭代器是故障快速修復(fù)的。這意味著,當(dāng)另一個(gè)線程修改底層集合的時(shí)候,如果您正在用Iterator遍歷集合,那么,Iterator就會(huì)拋出
ConcurrentModificationException異常并立刻失敗。
List接口繼承了Collection接口以定義一個(gè)允許重復(fù)項(xiàng)的有序集合。該接口不但能夠?qū)α斜淼囊徊糠诌M(jìn)行處理,還添加了面向位置的操作。
1、面向位置的操作包括插入某個(gè)元素,還包括獲取、除去或更改元素的功能。在List中搜索元素可以從列表的頭部或尾部開(kāi)始,如果找到元素,還將報(bào)告元素所在的位置:
Void add(int index,Object element):在指定位置Index上添加元素element
Boolean addAll(int index,Collection c):將集合C的所有元素添加到指定位置Index
Object get(int index):返回List中指定位置的元素
Int indexOf(Object o):返回第一個(gè)出現(xiàn)元素O的位置,否則返回-1
Int lastIndexOf(Object o):返回最后一個(gè)出現(xiàn)元素O的位置,否則返回-1
Object remove(int index):刪除指定位置上的元素
Object set(int index,Object element):用元素Element取代位置Index上的元素,并且返回舊的元素
2、List接口不但以位置序列迭代的遍歷整個(gè)列表,還能處理集合的子集:
ListIterator ListIterator():返回一個(gè)列表迭代器,用來(lái)訪問(wèn)列表中的元素
ListIterator ListIterator(int index):返回一個(gè)列表迭代器,用來(lái)從指定位置Index開(kāi)始訪問(wèn)列表中的元素
List subList(int formIndex,int toIndex):返回從指定位置FromIndex(包含)到ToIndex(不包含)范圍中各個(gè)元素的列表視圖對(duì)子列表的更改對(duì)底層List也有影響。
ListIterator接口繼承Iterator接口以支持添加或更改底層集體中的元素,還支持雙向訪問(wèn)。ListIterator沒(méi)有當(dāng)前位置,光標(biāo)位于調(diào)用
Previous和Next方法返回的值之間。一個(gè)長(zhǎng)度為N的列表,有N+1個(gè)有效索引值:
1、Void add(Object o):將對(duì)象O添加到當(dāng)前位置的前面
Void set(Object o):用對(duì)象O替代Next或Previous方法訪問(wèn)的上一個(gè)元素。如果上次調(diào)用后列表結(jié)構(gòu)被修改了,那么將拋出IIIegalStateException異常。
2、Boolean hasPrevious():判斷向后迭代時(shí)是否有元素可訪問(wèn)
Object previous():返回上一個(gè)對(duì)象
Int nextIndex():返回下次調(diào)用Next方法時(shí)將返回的元素的索引
Int previousIndex():返回下次調(diào)用Previous方法時(shí)將返回的元素的索引
有兩個(gè)抽象的List實(shí)現(xiàn)類(lèi):AbstractList和AbstractSequentialList。它們覆蓋了Equals()和HashCode()方法以確保兩個(gè)相等的集合返回相同的哈希碼。
在“集合框架”中有兩種常規(guī)的List實(shí)現(xiàn):ArrayList和LinkedList。如果要支持隨機(jī)訪問(wèn),而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可選的集合。但如果,您要
頻繁的從列表的中間位置添加和除去元素,而只要順序的訪問(wèn)列表元素,那么,LinkedList實(shí)現(xiàn)更好。
ArrayList和LinkedList都實(shí)現(xiàn)Cloneable接口,都提供了兩個(gè)構(gòu)造函數(shù),一個(gè)無(wú)參的,一個(gè)接受另一個(gè)Collection。
LinkedList類(lèi)添加了一些處理列表兩端元素的方法。
1、Void addFirst(Object o):將對(duì)象O添加到列表的開(kāi)頭。
Void addLast(Object o):將對(duì)象O添加到列表的結(jié)尾
2、Object getFirst():返回列表開(kāi)關(guān)的元素
Object getLast():返回列表結(jié)尾的元素
3、Object removeFirst():刪除并且返回列表開(kāi)關(guān)的元素
Object removeLast():刪除并且返回列表結(jié)尾的元素
4、LinkedList():構(gòu)建一個(gè)空的鏈接列表
Linked(Collection c):構(gòu)建一個(gè)鏈接列表,并且添加集合C的所有元素使用這些新方法,您就可以輕松的把LinkedList當(dāng)作一個(gè)堆棧、隊(duì)列或其它面向端點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
ArrayList類(lèi)封裝了一個(gè)動(dòng)態(tài)再分配的Object[]數(shù)組。每個(gè)ArrayList對(duì)象有一個(gè)Capacity。這個(gè)Capacity表示存儲(chǔ)列表中元素的數(shù)組的容量。當(dāng)元素添加到ArrayList時(shí),它的Capacity在常量
時(shí)間內(nèi)自動(dòng)增加。在向一個(gè)ArrayList對(duì)象添加大量元素的程序中,可使用ensureCapacity方法增加Capacity.這可以減少增加重分配的數(shù)量。
1、Void ensureCapacity(int minCapacity):將ArrayList對(duì)象容量增加MinCapacity
2、Void trimToSize():整理ArrayList對(duì)象容量為列表當(dāng)前大小。程序可使用這個(gè)操作減少ArrayList對(duì)象存儲(chǔ)空間。
Set接口繼承Collection接口,而且它不允許集合中存在重復(fù)項(xiàng),每個(gè)具體的Set實(shí)現(xiàn)類(lèi)依賴添加的對(duì)象的Equals()方法來(lái)檢查狂性。Set接口沒(méi)有引入新方法,所以Set就是一個(gè)
Collection,只不過(guò)其行為不同。
Hash表是一種數(shù)據(jù)結(jié)構(gòu),用來(lái)查找對(duì)象。Hash表為每個(gè)對(duì)象計(jì)算出一個(gè)整數(shù),稱為Hash Code(哈希碼)。Hash表是個(gè)鏈接式列表的陣列。每個(gè)列表稱為一個(gè)Buckets(哈希表元)。
對(duì)象位置的計(jì)算Index=HashCode%buckets。
在“集合框架”中有兩種比較接口:Comparable接口和Comparator接口。像String和Integer等Java內(nèi)建類(lèi)實(shí)現(xiàn)Comparable接口以提供一定排序方式,但這樣只能實(shí)現(xiàn)該接口一次。對(duì)
于那些沒(méi)有實(shí)現(xiàn)Comparable接口的類(lèi)、或者自定義的類(lèi),您可以通過(guò)Comparator接口來(lái)定義您自己的比較方式。
在Java.lang包中,Comparable接口適用于一個(gè)類(lèi)有自然順序的時(shí)候。假定對(duì)象集合是同一個(gè)類(lèi)型,該接口允許您把集合排序成自然順序。
Int compareTo(Object o):比較當(dāng)前實(shí)例對(duì)象與對(duì)象O,如果位于對(duì)象O之前,返回負(fù)值,如果兩個(gè)對(duì)象在排序中位置相同,則返回0,如果位于對(duì)象O后面,則返回正值。
SortedSet,它保持元素的有序順序。SortedSet接口為集合的視圖和它的兩端提供了訪問(wèn)方法。當(dāng)佻處理列表的子集時(shí),理性視圖會(huì)反映到源集。此外,更改源集也會(huì)反映在子集上。發(fā)
生這種情況的原因在于視圖由兩端的元素而不是下標(biāo)元素指定,所以如果您想要一個(gè)特殊的高端元素在子集中,您必須找到下一個(gè)元素。添加到SortedSet實(shí)現(xiàn)類(lèi)的元素必須實(shí)現(xiàn)
Comparable接口,否則您必須給它的構(gòu)造函數(shù)提供一個(gè)接口的實(shí)現(xiàn)。TreeSet類(lèi)是它的唯一一分實(shí)現(xiàn)。
1、Comparator comparator():返回對(duì)元素進(jìn)行排序時(shí)使用的比較器,如果使用Comparable接口的compareTo()方法對(duì)元素進(jìn)行比較,則返回Null。
2、Object first():返回有序集合中第一個(gè)元素。
3、Object last():返回有序集合中最后一個(gè)元素。
4、SortedSet subSet(Object fromElement,Object toElement):返回從formElement到ToElement范圍內(nèi)元素的SortedSet視圖。
5、SortedSet headSet(Object toElemtn):返回SortedSet的一個(gè)視圖,其內(nèi)各元素皆小于Toelement
6、SortedSet tailSet(Object fromElement):返回SortedSet的一個(gè)視圖,其內(nèi)各元素皆大于或等于FromElement
AbstractSet類(lèi)覆蓋了Object類(lèi)的equals()和hashCode()方法,以確保兩個(gè)相等的集返回相同的哈希碼。若兩個(gè)集大小相等且包含相同元素,則這兩個(gè)集相等。按定義,集的哈希碼是集中
元素哈希碼的總和。因此,不論集的內(nèi)部順序如何,兩個(gè)相等的集合有相同的哈希碼。
Object類(lèi)
1、Boolean equals(Object obj):對(duì)兩個(gè)對(duì)象進(jìn)行比較,以便確定它們是否相同
2、Int hashCode():返回該對(duì)象的哈希碼。相同的對(duì)象必須返回相同的哈希碼
“集合框架”支持Set接口兩種普通的實(shí)現(xiàn):HashSet和TreeSet。HashSet存儲(chǔ)重復(fù)自由的集合。當(dāng)您要從集合中以有序的方式插入和抽取元素時(shí),TreeSet實(shí)現(xiàn)會(huì)有用處。為了能順利進(jìn)
行,添加到TreeSet的元素必須是可排序的。
HashSet類(lèi)
1、HashSet():構(gòu)建一個(gè)空的哈希集
2、HashSet(Collection c):構(gòu)建一個(gè)哈希集,并且添加集合C中所有元素
3、HashSet(int initialCapacity):構(gòu)建一個(gè)擁有特定容量的空哈希集
4、HashSet(int initialCapacity,float loadFactor):構(gòu)建一個(gè)擁有特定容量和加載因子的空哈希集。LoadFactor是0至1之間的一個(gè)數(shù)
TreeSet類(lèi)
1、TreeSet():構(gòu)建一個(gè)空的樹(shù)集
2、TreeSet(Collection c):構(gòu)建一個(gè)樹(shù)集,并且添加集合C中所有元素
3、TreeSet(Comparator c):構(gòu)建一個(gè)樹(shù)集,并且使用特定的比較器對(duì)其元素進(jìn)行排序
4、TreeSet(SortedSet S):構(gòu)建一個(gè)樹(shù)集,添加有序集合S中所有元素,并且使用與有序集合S相同的比較器排序。
LinkedHashSet的迭代器按照元素的插入順序來(lái)訪問(wèn)各個(gè)元素。它提供了一個(gè)可以快速訪問(wèn)各個(gè)元素的有序集合。同時(shí),它也增加了實(shí)現(xiàn)的代價(jià),因?yàn)楣1碓械母鱾€(gè)元素是通過(guò)雙重
鏈接式列表鏈接在的。
1、LinkedHashSet():構(gòu)建一個(gè)空的鏈接式哈希集
2、LinkedHashSet(Collection c):構(gòu)建一個(gè)鏈接式哈希集,并且添加集合C中所有元素
3、LinkedHashSet(int initialCapacity):構(gòu)建一個(gè)擁有特定容量的空鏈接式哈希集
4、LinkedHashSet(int initialCapacity,float loadFactor):構(gòu)建一個(gè)擁有特定容量和加載因子的空鏈接式哈希集。LoadFactor是0至1之間的一個(gè)數(shù)。
Map接口用于維護(hù)鍵/值對(duì)。該接口描述了從不重復(fù)的鍵到值的映射
1、添加、刪除操作
Object put(Object key,Object value):將互相關(guān)聯(lián)的一個(gè)關(guān)鍵字與一個(gè)值放入該映像。如果該關(guān)鍵字已經(jīng)存在,那么與此關(guān)鍵字相關(guān)的新值
將取代舊值。方法返回關(guān)鍵字的舊值,如果關(guān)鍵字原先并不存在,則返回Null
Object remove(Object key):從映像中刪除與Key相關(guān)的映射
Void putAll(Map t):將來(lái)自特定映像的所有元素添加到該映像
Void clear():從映像中刪除所有映射
2、查詢操作:
Object get(Object key):獲得與關(guān)鍵字Key相關(guān)的值,并且返回與關(guān)鍵字Key相關(guān)的對(duì)象,如果沒(méi)有在該映像中找到該關(guān)鍵字,則返回Null
Boolean containsKey(Object key):判斷映像中是否存在關(guān)鍵字Key
Boolean containsValue(Object value):判斷映像中是否存在值Value
Int size():返回當(dāng)前映像中映射的數(shù)量
Boolean isEmpty():判斷映像中是否有任何映射
3、視圖操作:處理映像中鍵/值對(duì)組
Set keySet():返回映像中所有關(guān)鍵字的視圖集
Collection values():返回映像中所有值的視圖集
Set entrySet():返回Map.Entry對(duì)象的視圖集,即映像中的關(guān)鍵字/值對(duì)
Map的entrySet()方法返回一個(gè)實(shí)現(xiàn)Map.Entry接口的對(duì)象集合。集合中每個(gè)對(duì)象都是底層Map中一個(gè)特定的鍵/值對(duì)。通過(guò)這個(gè)集合的迭代器,您可以獲得每一個(gè)條目的鍵或值并對(duì)值進(jìn)行更
改。當(dāng)條目通過(guò)迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的條目的setValue()方法,其余對(duì)源Map外部的修改都會(huì)導(dǎo)致此條目集變得無(wú)效,同時(shí)產(chǎn)生條目行為未定
義。
Object getKey():返回條目的關(guān)鍵字
Object getValue():返回條目的值
Obect setValue(Object value):將相關(guān)映像中的值改為value,并且返回舊值。
“集合框架”提供了個(gè)特殊的Map接口:SortedMap,它用來(lái)保持鍵的有序順序。SortedMap接口為映像的視圖(子集),包括兩個(gè)端點(diǎn)提供了訪問(wèn)方法。除了排序是作用于映射的鍵以
外,處理SortedMap和處理SortedSet一樣。添加到SortedMap實(shí)現(xiàn)類(lèi)的元素必須實(shí)現(xiàn)Comparable接口,否則您必須給它的構(gòu)造函數(shù)提供一個(gè)Comparator接口的實(shí)現(xiàn)。TreeMap類(lèi)是它的
唯一一份實(shí)現(xiàn)。
“因?yàn)閷?duì)于映射來(lái)說(shuō),每個(gè)鍵只能對(duì)應(yīng)一個(gè)值,如果在添加一個(gè)鍵/值對(duì)時(shí)比較兩個(gè)鍵產(chǎn)生了0返回值(通過(guò)Comparable的compareTo()方法或通過(guò)Comparator的compare()方法),
那么,原始鍵對(duì)應(yīng)值被新的值替代。如果兩個(gè)元素相等,那還好。但如果不相等,那么您就應(yīng)該修改比較方法,讓比較方法和 equals() 的效果一致。”
(1) Comparator comparator(): 返回對(duì)關(guān)鍵字進(jìn)行排序時(shí)使用的比較器,如果使用Comparable接口的compareTo()方法對(duì)關(guān)鍵字進(jìn)行比較,則返回null
(2) Object firstKey(): 返回映像中第一個(gè)(最低)關(guān)鍵字
(3) Object lastKey(): 返回映像中最后一個(gè)(最高)關(guān)鍵字
(4) SortedMap subMap(Object fromKey, Object toKey): 返回從fromKey(包括)至toKey(不包括)范圍內(nèi)元素的SortedMap視圖(子集)
(5) SortedMap headMap(Object toKey): 返回SortedMap的一個(gè)視圖,其內(nèi)各元素的key皆小于toKey
(6) SortedSet tailMap(Object fromKey): 返回SortedMap的一個(gè)視圖,其內(nèi)各元素的key皆大于或等于fromKey
4.3. AbstractMap抽象類(lèi)
和其它抽象集合實(shí)現(xiàn)相似,AbstractMap 類(lèi)覆蓋了equals()和hashCode()方法以確保兩個(gè)相等映射返回相同的哈希碼。如果兩個(gè)映射大小相等、包含同樣的鍵且每個(gè)鍵在這兩個(gè)映射
中對(duì)應(yīng)的值都相同,則這兩個(gè)映射相等。映射的哈希碼是映射元素哈希碼的總和,其中每個(gè)元素是Map.Entry接口的一個(gè)實(shí)現(xiàn)。因此,不論映射內(nèi)部順序如何,兩個(gè)相等映射會(huì)報(bào)告相同的
哈希碼。
4.4. HashMap類(lèi)和TreeMap類(lèi)
“集合框架”提供兩種常規(guī)的Map實(shí)現(xiàn):HashMap和TreeMap (TreeMap實(shí)現(xiàn)SortedMap接口)。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但如果您要按自然順序
或自定義順序遍歷鍵,那么TreeMap會(huì)更好。使用HashMap要求添加的鍵類(lèi)明確定義了hashCode()和equals()的實(shí)現(xiàn)。
這個(gè)TreeMap沒(méi)有調(diào)優(yōu)選項(xiàng),因?yàn)樵摌?shù)總處于平衡狀態(tài)。
4.4.1. HashMap類(lèi)
為了優(yōu)化HashMap空間的使用,您可以調(diào)優(yōu)初始容量和負(fù)載因子。
(1) HashMap(): 構(gòu)建一個(gè)空的哈希映像
(2) HashMap(Map m): 構(gòu)建一個(gè)哈希映像,并且添加映像m的所有映射
(3) HashMap(int initialCapacity): 構(gòu)建一個(gè)擁有特定容量的空的哈希映像
(4) HashMap(int initialCapacity, float loadFactor): 構(gòu)建一個(gè)擁有特定容量和加載因子的空的哈希映像
4.4.2. TreeMap類(lèi)
TreeMap沒(méi)有調(diào)優(yōu)選項(xiàng),因?yàn)樵摌?shù)總處于平衡狀態(tài)。
(1) TreeMap():構(gòu)建一個(gè)空的映像樹(shù)
(2) TreeMap(Map m): 構(gòu)建一個(gè)映像樹(shù),并且添加映像m中所有元素
(3) TreeMap(Comparator c): 構(gòu)建一個(gè)映像樹(shù),并且使用特定的比較器對(duì)關(guān)鍵字進(jìn)行排序
(4) TreeMap(SortedMap s): 構(gòu)建一個(gè)映像樹(shù),添加映像樹(shù)s中所有映射,并且使用與有序映像s相同的比較器排序
4.5. LinkedHashMap類(lèi)
LinkedHashMap擴(kuò)展HashMap,以插入順序?qū)㈥P(guān)鍵字/值對(duì)添加進(jìn)鏈接哈希映像中。象LinkedHashSet一樣,LinkedHashMap內(nèi)部也采用雙重鏈接式列表。
(1) LinkedHashMap(): 構(gòu)建一個(gè)空鏈接哈希映像
(2) LinkedHashMap(Map m): 構(gòu)建一個(gè)鏈接哈希映像,并且添加映像m中所有映射
(3) LinkedHashMap(int initialCapacity): 構(gòu)建一個(gè)擁有特定容量的空的鏈接哈希映像
(4) LinkedHashMap(int initialCapacity, float loadFactor): 構(gòu)建一個(gè)擁有特定容量和加載因子的空的鏈接哈希映像
(5) LinkedHashMap(int initialCapacity, float loadFactor,
boolean accessOrder): 構(gòu)建一個(gè)擁有特定容量、加載因子和訪問(wèn)順序排序的空的鏈接哈希映像
“如果將accessOrder設(shè)置為true,那么鏈接哈希映像將使用訪問(wèn)順序而不是插入順序來(lái)迭代各個(gè)映像。每次調(diào)用get或者put方法時(shí),相關(guān)的映射便從它的當(dāng)前位置上刪除,然后放到鏈
接式映像列表的結(jié)尾處(只有鏈接式映像列表中的位置才會(huì)受到影響,哈希表元?jiǎng)t不受影響。哈希表映射總是待在對(duì)應(yīng)于關(guān)鍵字的哈希碼的哈希表元中)。”
“該特性對(duì)于實(shí)現(xiàn)高速緩存的“刪除最近最少使用”的原則很有用。例如,你可以希望將最常訪問(wèn)的映射保存在內(nèi)存中,并且從數(shù)據(jù)庫(kù)中讀取不經(jīng)常訪問(wèn)的對(duì)象。當(dāng)你在表中找不到
某個(gè)映射,并且該表中的映射已經(jīng)放得非常滿時(shí),你可以讓迭代器進(jìn)入該表,將它枚舉的開(kāi)頭幾個(gè)映射刪除掉。這些是最近最少使用的映射。”
(6) protected boolean removeEldestEntry(Map.Entry eldest): 如果你想刪除最老的映射,則覆蓋該方法,以便返回true。當(dāng)某個(gè)映射已經(jīng)添加給映像之后,便調(diào)用該方法。它的默認(rèn)
實(shí)現(xiàn)方法返回false,表示默認(rèn)條件下老的映射沒(méi)有被刪除。但是你可以重新定義本方法,以便有選擇地在最老的映射符合某個(gè)條件,或者映像超過(guò)了某個(gè)大小時(shí),返回true。
4.6. WeakHashMap類(lèi)
WeakHashMap是Map的一個(gè)特殊實(shí)現(xiàn),它使用WeakReference(弱引用)來(lái)存放哈希表關(guān)鍵字。使用這種方式時(shí),當(dāng)映射的鍵在 WeakHashMap的外部不再被引用時(shí),垃圾收集器會(huì)
將它回收,但它將把到達(dá)該對(duì)象的弱引用納入一個(gè)隊(duì)列。WeakHashMap的運(yùn)行將定期檢查該隊(duì)列,以便找出新到達(dá)的弱應(yīng)用。當(dāng)一個(gè)弱引用到達(dá)該隊(duì)列時(shí),就表示關(guān)鍵字不再被任何人
使用,并且它已經(jīng)被收集起來(lái)。然后WeakHashMap便刪除相關(guān)的映射。
(1) WeakHashMap(): 構(gòu)建一個(gè)空弱哈希映像
(2) WeakHashMap(Map t): 構(gòu)建一個(gè)弱哈希映像,并且添加映像t中所有映射
(3) WeakHashMap(int initialCapacity): 構(gòu)建一個(gè)擁有特定容量的空的弱哈希映像
(4) WeakHashMap(int initialCapacity, float loadFactor): 構(gòu)建一個(gè)擁有特定容量和加載因子的空的弱哈希映像
4.6. IdentityHashMap類(lèi)
IdentityHashMap也是Map的一個(gè)特殊實(shí)現(xiàn)。在這個(gè)類(lèi)中,關(guān)鍵字的哈希碼不應(yīng)該由hashCode()方法來(lái)計(jì)算,而應(yīng)該由System.identityHashCode方法進(jìn)行計(jì)算(即使已經(jīng)重新定義了
hashCode方法)。這是Object.hashCode根據(jù)對(duì)象的內(nèi)存地址來(lái)計(jì)算哈希碼時(shí)使用的方法。另外,為了對(duì)各個(gè)對(duì)象進(jìn)行比較,IdentityHashMap將使用==,而不使用equals方法。
換句話說(shuō),不同的關(guān)鍵字對(duì)象,即使它們的內(nèi)容相同,也被視為不同的對(duì)象。IdentityHashMap類(lèi)可以用于實(shí)現(xiàn)對(duì)象拓?fù)浣Y(jié)構(gòu)轉(zhuǎn)換(topology-preserving object graph transformations)
(比如實(shí)現(xiàn)對(duì)象的串行化或深度拷貝),在進(jìn)行轉(zhuǎn)換時(shí),需要一個(gè)“節(jié)點(diǎn)表”跟蹤那些已經(jīng)處理過(guò)的對(duì)象的引用。即使碰巧有對(duì)象相等,“節(jié)點(diǎn)表”也不應(yīng)視其相等。另一個(gè)應(yīng)用是維護(hù)代理
對(duì)象。比如,調(diào)試工具希望在程序調(diào)試期間維護(hù)每個(gè)對(duì)象的一個(gè)代理對(duì)象。
“IdentityHashMap類(lèi)不是一般意義的Map實(shí)現(xiàn)!它的實(shí)現(xiàn)有意的違背了Map接口要求通過(guò)equals方法比較對(duì)象的約定。這個(gè)類(lèi)僅使用在很少發(fā)生的需要強(qiáng)調(diào)等同性語(yǔ)義的情況。”
(1) IdentityHashMap (): 構(gòu)建一個(gè)空的全同哈希映像,默認(rèn)預(yù)期最大尺寸為21“預(yù)期最大尺寸是映像期望把持的鍵/值映射的最大數(shù)目”
(2) IdentityHashMap (Map m): 構(gòu)建一個(gè)全同哈希映像,并且添加映像m中所有映射
(3) IdentityHashMap (int expectedMaxSize): 構(gòu)建一個(gè)擁有預(yù)期最大尺寸的空的全同哈希映像。放置超過(guò)預(yù)期最大尺寸的鍵/值映射時(shí),將引起內(nèi)部數(shù)據(jù)結(jié)構(gòu)的增長(zhǎng),有時(shí)可能很費(fèi)時(shí)。