一.Java集合類(lèi)概述
1.集合類(lèi):為了保存數量不確定的數據,以及具有映射關(guān)系的數據(關(guān)聯(lián)數組)。集合類(lèi)主要負責保存和盛裝其他數據,因此集合類(lèi)又叫做容器類(lèi)。
2.集合類(lèi)與數組的區別:
① 集合類(lèi)中的數據數量不確定,而數組中數據的數量確定。
② 數組中的數據既可以是基本數據類(lèi)型,又可以是對象。而集合類(lèi)中只能保存對象。
3.Java集合框架的根接口:Collection和 Map
Map保存的的每一項數據都是一個(gè)key-value對,其中 key是不重復的。
二.Collection接口和 Iterator接口
1.Collection 接口
add,addAll,clear,contains,containAll,,remove,removeAll,size,isEmpty,toArray,iterator,re-tainAll等
2.Iterator 接口
Iterator對象被稱(chēng)為迭代器,用于遍歷集合中的元素。
三個(gè)方法:hasNext, next,remove
注意:
① 使用Iterator對集合元素進(jìn)行迭代時(shí),并不是把集合元素本身賦給迭代變量,而是把集合元素的值賦給迭代變量,所以修改迭代元素的值對于集合不會(huì )有任何影響。
② 使用Iterator對集合元素進(jìn)行迭代時(shí),集合元素不能被改變(Iterator的 remove方法除外),否則會(huì )產(chǎn)生異常。
3.foreach循環(huán)
利用 foreach循環(huán)也可以遍歷集合中的元素。
與 Iterator注意的兩點(diǎn)相同。
三.Set接口
Set集合類(lèi)似于一個(gè)罐子,其中的元素無(wú)序且不相等。Set集合判斷兩個(gè)元素是否相等是根據equal方法,而不是根據“ ==”來(lái)判斷。
1.HashSet類(lèi)
HashSet是根據哈希算法來(lái)存取集合中的元素。
HashSet集合判斷兩個(gè)元素相等的標準是:通過(guò)equals方法比較兩個(gè)對象相等,并且hashCode方法的返回值也相等。
注意:
① 如果一個(gè)類(lèi)重寫(xiě)equals方法,那么相應的也要重寫(xiě)hashCode方法。規則是:如果兩個(gè)對象通過(guò) equals方法比較返回true,那么它們的 hashCode方法的返回值也應該相同。
② 當向HashSet集合中添加可變對象時(shí)要格外注意,因為通過(guò)對可變對象的修改可能會(huì )導致 HashSet集合中的兩個(gè)元素完全相同,但是又處于不同的位置,從而導致 HashSet集合無(wú)法準確的訪(fǎng)問(wèn)該對象。
LinkedHashSet類(lèi),是HashSet的子類(lèi),與HashSet類(lèi)不同的是,它通過(guò)鏈表維持集合中元素的順序,使得集合中的元素看起來(lái)時(shí)按照插入順序保存的。
2.TreeSet類(lèi)
繼承了SortedSet接口,確保集合中的元素處于排序狀態(tài)。
與HashSet類(lèi)相比增加了如下幾個(gè)方法:
first,last,lower,higher,subset,headSet,tailSet,comparator
TreeSet并不是按照元素的插入順序進(jìn)行排序, TreeSet支持兩種排序算法:自然排序和定制排序。
·自然排序: TreeSet調用元素的compareTo方法來(lái)比較元素的大小關(guān)系,然后按照升序排列。如果試圖將一個(gè)對象加入 TreeSet集合,那么這個(gè)對象所對應的類(lèi)必須實(shí)現Comparable接口,否則會(huì )拋出異常。向TreeSet集合中加入的必須是同一類(lèi)型的對象,否則也會(huì )拋出異常。
TreeSet集合中兩個(gè)對象完全相同的標準是:通過(guò) equals方法比較返回true,并且同 compareTo方法比較返回0.
當向 TreeSet中加入可變對象時(shí)要格外注意,對可變對象修改后,排序不會(huì )發(fā)生變化,刪除元素也可能會(huì )失敗,因為 TreeSet中可能存在兩個(gè)完全相同的元素。
總之,不要向 HashSet和 TreeSet中加入可變對象。
·定制排序:通過(guò) Comparator接口實(shí)現。加入TreeSet集合中的元素沒(méi)有必要再實(shí)現 Comparable接口,但是加入加入TreeSet集合中的元素仍然需要是同一類(lèi)型。
3.EnumSet類(lèi)
EnumSet是專(zhuān)為枚舉類(lèi)設計的集合類(lèi),EnumSet集合的元素必須為指定枚舉類(lèi)型的枚舉值。
EnumSet沒(méi)有暴露任何構造方法來(lái)構造該類(lèi)的對象,要構造該類(lèi)的對象必須通過(guò)EnumSet本身提供的靜態(tài)方法。
主要的靜態(tài)方法如下:
allOf,noneOf,of,range,copyof(EnumSet),copyOf(Collection),complementOf
如何選擇實(shí)現Set接口的各個(gè)類(lèi):
·HashSet 類(lèi)的性能總是比TreeSet 類(lèi)的性能要好,而TreeSet 類(lèi)在需要排序時(shí)才使用。
·HashSet 類(lèi)的性能比LinkedHashSet 類(lèi)的性能也要略好一些,但是LinkedHashSet 類(lèi)在遍歷集合元素時(shí)要快一些。
·EnumSet 是所有的Set 實(shí)現類(lèi)中性能最好的,但是只能保存枚舉類(lèi)型的元素。
·Set 實(shí)現類(lèi)都不是線(xiàn)程安全的。
四.List接口
List是一個(gè)有序的集合,List集合中的每一個(gè)元素都有其對應的索引,所以List集合中的元素允許重復。 List按照添加元素的先后順序設置索引。
1.List接口與ListIterator接口
與Collection接口不同, List接口中增加一些根據索引操作元素的方法。
List接口中的方法:
·添加元素: add(Object),add(index,Object),addAll(Collection),addAll(index,Collection)
·刪除元素: remove(Object),removeAll(Collection),remove(index)
·獲取元素:get(index)
·替換元素:set(index,Object)
·截取元素: subList(fromIndex,toIndex)
·返回索引值: indexOf(Object),lastIndexOf(Object)
ListIterator接口是Iterator接口的子接口,它增加了一些新的方法,專(zhuān)門(mén)用來(lái)操作 List集合。
ListIterator接口中新增加的方法有:
·hasPrevious()
·previous()
·add()
2.ArrayList 和Vector實(shí)現類(lèi)
ArrayList和Vector類(lèi)都是基于數組實(shí)現的,所以 ArrayList和Vector都封裝了一個(gè)動(dòng)態(tài)分配大小的數組 Object[]。ArrayList和 Vector類(lèi)都有一個(gè)屬性capacity,表示它們封裝的數組 Object[]的大小,capacity會(huì )隨集合中元素的個(gè)數變化而自動(dòng)變化。
ArrayList和Vector類(lèi)可以通過(guò)以下方法來(lái)操作 capacity屬性:
·ensureCapacity(minCapacity)
·trimToSize()
Vector類(lèi)提供了一個(gè)子類(lèi)Stack類(lèi)用來(lái)模擬“?!边@種數據結構。 Stack具有的方法如下:
·push(Object)
·pop()
·peek()
3.固定長(cháng)度的List
Arrays.ArrayList類(lèi):可以將一個(gè)數組或者指定個(gè)數的對象轉換成一個(gè)List集合。不能進(jìn)行插入和刪除操作,只能遍歷。
五.Queue接口
Queue接口模擬隊列這種特殊的數據結構,主要的方法如下:
add(),offer(),element(),peek(),poll(),remove()
1.LinkedList 實(shí)現類(lèi)
LinkedList類(lèi)既可以當做雙向隊列來(lái)使用,也可以當做棧來(lái)使用,還可以當做List集合來(lái)使用。
LinkedList類(lèi)與ArrayList和 Vector類(lèi)的實(shí)現機制完全不同,ArrayList和 Vector類(lèi)內部是以數組的形式保存元素,所以隨機訪(fǎng)問(wèn)性能較好,而 LinkedList類(lèi)是以鏈表的形式保存元素,所以隨機訪(fǎng)問(wèn)性能較差,但是在迭代訪(fǎng)問(wèn)元素,插入、刪除元素方面性能較好。
關(guān)于List 集合實(shí)現類(lèi)的選擇問(wèn)題:
· 如果需要遍歷集合中的元素,對于ArrayList和 Vector類(lèi)最好使用隨機訪(fǎng)問(wèn)( get())的方法,對于 LinkedList類(lèi)最好使用迭代器遍歷。
· 如果需要經(jīng)常執行插入和刪除操作來(lái)改變集合的大小,則應該選用 LinkedList類(lèi),而不要使用 ArrayList類(lèi)和 Vector類(lèi)。
· 如果需要多條線(xiàn)程同時(shí)訪(fǎng)問(wèn)List 集合,則可以考慮使用Vector 類(lèi)來(lái)同步實(shí)現。
2.PriorityQueue實(shí)現類(lèi)
對于PriorityQueue集合中的元素也是按照大小排序,排序的規則與 TreeSet類(lèi)相同,也分自然排序和定制排序兩種。
六.Map接口
首先可以將 Map接口理解成一個(gè)特殊的Set接口,只是該 Set接口中保存的元素都比較特殊,每個(gè)元素都是一個(gè)Entry對象, Entry類(lèi)封裝了一個(gè)key-value對,它有三個(gè)方法:
· Object getKey()
· Object getValue()
· Object setValue(value)
其次也可以將 Map接口理解成一個(gè)特殊的List接口,只是 List接口中用整數值做索引,而Map接口中用 key值做索引,key可以為任意對象。
Map接口用于保存映射數據,它里面保存有兩組數據,一組用來(lái)保存key,一組用來(lái)保存 value。Key不允許重復。Map有時(shí)也被稱(chēng)為字典或者關(guān)聯(lián)數組。
Map接口提供的方法:
·添加元素:put(Object key,Object value),putAll(Map m)
·刪除元素:remove(Object key)
·清除所有元素:clear()
·獲取元素:get(Object key)
·測試: containsKey(key),containsValue(value),isEmpty()
·集合大?。?/span>size()
·轉化:Collection values(),Set keyset(),Set entrySet()
1.HashMap 和Hashtable類(lèi)
HashMap類(lèi)和Hashtable類(lèi)的關(guān)系就像 ArrayList和Vector類(lèi)的關(guān)系一樣。
HashMap和Hashtable類(lèi)的區別:
·Hashtable是一個(gè)線(xiàn)程安全類(lèi),而 HashMap不是線(xiàn)程安全的。但是HashMap性能比 Hashtable性能高一些。
·Hashtable不允許 null作為key或者value,而 HashMap允許。但在HashMap集合中最多有一個(gè) key為null,但是可以有多個(gè)value為null。
HashMap和Hashtable類(lèi)也不能保證其中 key-value對的順序,但是它們中的key必須實(shí)現 equals和hashCode方法。
HashMap和Hashtable類(lèi)判斷兩個(gè) key值是否相等標準:通過(guò)equals方法比較返回 true,并且具有相同的hashcode。
HashMap和Hashtable類(lèi)判斷兩個(gè) value值是否相等標準:通過(guò)equals方法比較返回 true。
與HashSet類(lèi)似,盡量不要使用可變對象作為 HashMap和Hashtable的 key。
HashMap的子類(lèi)LinkedHashMap:與 HashMap不同的是它可以維護元素的迭代順序,在性能上略差于 HashMap,迭代速度卻高于HashMap。
Hashtable的子類(lèi) Properties類(lèi):
Properties類(lèi)用來(lái)將Map對象與屬性文件關(guān)聯(lián)起來(lái),從而可以將 Map對象中的key-value對加入到屬性文件,同時(shí)也可以將屬性文件中的內容加入到 Map對象中。
由于屬性文件中的“屬性名”和“屬性值”都是字符串類(lèi)型,所以 Properties文件中的key和 value也都是字符串類(lèi)型。
Properties類(lèi)主要提供如下幾個(gè)方法:
·String getProperty(String key)
·String getProperty(String key,String defaultValues)
·void setProperty(String key,String value)
·void load(InputStream is)
·void store(OutputStream os,String comments)
3.SortedMap 接口和TreeMap實(shí)現類(lèi)
與SortedSet接口和 TreeMap實(shí)現類(lèi)完全類(lèi)似。
4.WeakHashMap 實(shí)現類(lèi)
WeakHashMap類(lèi)與HashMap類(lèi)基本相同,不同的是 HashMap的key保留了對實(shí)際對象的強引用,而WeakHashMap類(lèi)的 key保留了對實(shí)際對象的弱引用。
5.IdentityHashMap類(lèi)
IdentityHashMap類(lèi)與HashMap類(lèi)基本相同,不同的是IdentityHashMap類(lèi)在判斷 key值相等時(shí),必須保證代表key值的兩個(gè)對象完全相等時(shí)才認為是相等的。
6.EnumMap 類(lèi)
EnumMap是一個(gè)與枚舉類(lèi)一起使用的Map實(shí)現,它要求 key值必須是一個(gè)枚舉類(lèi)的枚舉值,創(chuàng )建EnumMap類(lèi)時(shí)必須顯示或者隱式的指定它對應的枚舉類(lèi)。
EnumMap不允許使用null作為 key值,但是允許null作為 value值。
Map 集合的選擇問(wèn)題:
· HashMap和 Hashtable類(lèi)的效率基本相同,但 HashMap的性能可能比 Hashtable要好一些,因為 HashMap沒(méi)有實(shí)現同步操作。
·TreeMap 類(lèi)的性能不如HashMap ,但是TreeMap 類(lèi)中的key-value 對都是有序的。
·LinkedHashMap 的性能比HashMap 略差一點(diǎn),因為它要維護key 的插入順序。
·EnumMap 的性能最好,但是它要求必須要將一個(gè)枚舉類(lèi)中的元素作為key。
七.HashSet和 HashMap的性能選項
桶: hash表中可以存儲元素的位置。
HashSet和HashMap的 hash表都有以下性能選項:
·容量( capacity):hash表中桶的數量
·初始化容量( initialCapacity):創(chuàng )建hash表時(shí)指定的桶的數量。
·尺寸( size):當前散列表中記錄的數量
·負載因子( loadFactor):size/capacity,輕負載的散列表具有沖突少,插入方便,易查詢(xún)的優(yōu)點(diǎn)。
負載極限:負載極限的值在 0-1之間,當超過(guò)負載極限時(shí),會(huì )成倍的增加容量(rehashing)。
八.操作集合的工具類(lèi)Collections
Java提供了一個(gè)操作Set,List, Map等集合的工具類(lèi):Collections。
1.排序操作
Collections提供了一下幾個(gè)方法用于對List集合進(jìn)行排序(都是靜態(tài)的):
·reverse(list):反轉集合中的元素
·shuffle(list):對集合中的元素進(jìn)行隨機排序
·sort(list):根據自然順序對集合中的元素進(jìn)行排序
·sort(list,comparator):根據定制順序對集合中的元素進(jìn)行排序
·swap(list,i,j):將 i和j處的元素進(jìn)行交換
·rotate(list,i):將 i和list.length-1-i處的元素進(jìn)行交換
2.查找、替換操作
Collections提供了一下幾個(gè)方法用于對List集合進(jìn)行查找、替換(都是靜態(tài)的):
·binarySearch(list,object):查找指定元素在list中的索引,但執行此方法前必須保證list已經(jīng)處于有序狀態(tài)。
·max(collection):按照自然排序查找 collection中的最大值
·max(collection,comparator):按照定制排序查找collection中的最大值
·min(collection):按照自然排序查找 collection中的最小值
·min(collection,comparator): 按照定制排序查找collection中的最小值
·fill(list,object):使用指定元素 object替換list中的所有元素
·frequency(colletion,object):返回集合collection中object元素出現的次數
· replaceAll(list,oldval,newval):用新的元素 newval替代list中所有舊的元素oldval
3.同步控制
Collections提供了多個(gè) synchronizedXxx方法用來(lái)同步集合對象,可以解決多線(xiàn)程并發(fā)訪(fǎng)問(wèn)集合時(shí)的線(xiàn)程安全問(wèn)題。
4.設置不可變的集合
Collections提供了三個(gè)方法返回一個(gè)不可變的集合:
·emptyXxx():返回一個(gè)空的不可變的集合對象。
·singleton(object):返回一個(gè)只包含一個(gè)元素 object的集合對象。
·unmodifiableXxx(colletion or map):返回一個(gè)不可變的視圖。