集合框架概述
- 一方面,面向?qū)ο笳Z言對(duì)事物的體現(xiàn)都是以對(duì)象的形式扎瓶,為了方便對(duì)多個(gè)對(duì)象的操作颗祝,就要對(duì)對(duì)象進(jìn)行存儲(chǔ)浊闪。另一方面,使用Array存儲(chǔ)對(duì)象方面具有一些弊端螺戳,而Java集合就像一種容器搁宾,可以動(dòng)態(tài)地把多個(gè)對(duì)象的引用放入容器中。
-
數(shù)組在內(nèi)存存儲(chǔ)方面的特點(diǎn):
- 數(shù)組初始化以后倔幼,長(zhǎng)度就確定了盖腿;
- 數(shù)組聲明的類型,就決定了進(jìn)行元素初始化時(shí)的類型损同;
-
數(shù)組在存儲(chǔ)數(shù)據(jù)方面的弊端:
- 數(shù)組初始化以后翩腐,長(zhǎng)度就不可變了,不便于擴(kuò)展膏燃;
- 數(shù)組中提供的屬性和方法少茂卦,不便于進(jìn)行添加、刪除组哩、插入等操作等龙,且效率不高处渣。同時(shí)無法直接獲取存儲(chǔ)元素的個(gè)數(shù);
- 數(shù)組存儲(chǔ)的數(shù)據(jù)是有序的而咆、可以重復(fù)的。-->存儲(chǔ)數(shù)據(jù)的特點(diǎn)單一幕袱;
-
數(shù)組在內(nèi)存存儲(chǔ)方面的特點(diǎn):
- Java集合類可以用于存儲(chǔ)數(shù)量不等的多個(gè)對(duì)象暴备,還可用于保存具有映射關(guān)系的關(guān)聯(lián)數(shù)組。
集合框架
兩種體系
Java集合可分為Collection
和Map
兩種體系:
-
Collection
接口:單列數(shù)據(jù)们豌,定義了存取一組對(duì)象的方法的集合涯捻,未提供直接實(shí)現(xiàn)類-
List
:元素有序、可重復(fù)的集合 -
Set
:元素?zé)o序望迎、不可重復(fù)的集合
-
-
Map
接口:雙列數(shù)據(jù)障癌,保存具有映射關(guān)系"key-value對(duì)"的集合,提供了直接的實(shí)現(xiàn)類
繼承和實(shí)現(xiàn)關(guān)系
|---- Collection接口:?jiǎn)瘟屑? |----List接口
|----Vector實(shí)現(xiàn)類
|----ArrayList實(shí)現(xiàn)類
|----LinkedList實(shí)現(xiàn)類
|----Set接口
|----HashSet實(shí)現(xiàn)類
|----LinkedHashSet實(shí)現(xiàn)類
|----SortedSet接口
|----TreeSet實(shí)現(xiàn)類
|----Map接口:雙列集合
|----Hashtable實(shí)現(xiàn)類
|----Properties實(shí)現(xiàn)類
|----HashMap實(shí)現(xiàn)類
|----LinkedHashMap實(shí)現(xiàn)類
|----SortedMap接口
|----TreeMap實(shí)現(xiàn)類
JDK提供的集合API位于java.util包內(nèi)辩尊,下圖中:
- 實(shí)線表示繼承關(guān)系
- 虛線表示實(shí)現(xiàn)關(guān)系
Collection接口繼承樹
Map接口繼承樹
Collection接口
Collection
接口是List
涛浙、Set
和Queue
接口的父接口,該接口里定義的方法既可用于操作Set
集合摄欲,也可用于操作List
和Queue
集合轿亮。
JDK不提供此接口的任何直接實(shí)現(xiàn),而是提供更具體的子接口(如:Set
和List
)實(shí)現(xiàn)胸墙。
在Java5之前我注,Java集合會(huì)丟失容器中所有對(duì)象的數(shù)據(jù)類型,把所有對(duì)象都當(dāng)成Object類型處理迟隅;從 JDK 5.0 增加了泛型以后但骨,Java集合可以記住容器中對(duì)象的數(shù)據(jù)類型。
Collection接口中的方法
-
添加
- add(Object obj)
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection);
- addAll(Collection coll)
Collection collection2 = new ArrayList(); collection2.add(new Date()); collection2.addAll(collection); System.out.println(collection2);
-
獲取有效元素的個(gè)數(shù)
- int size()
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection.size());
-
清空集合
- void clear()
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection.size()); collection.clear(); System.out.println(collection.size());
-
是否是空集合
- boolean isEmpty()
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection.size()); collection.clear(); System.out.println(collection.isEmpty());
- 是否包含某個(gè)元素
- boolean contains(Object obj):是通過元素的equals方法來判斷是否是同一個(gè)對(duì)象
Collection collection = new ArrayList();
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
System.out.println(collection.contains(123));
- boolean containsAll(Collection c):也是調(diào)用元素的equals方法來比較的智袭。拿兩個(gè)集合的元素挨個(gè)比較奔缠。
Collection collection = new ArrayList();
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
System.out.println(collection.containsAll(Arrays.asList(123,"BB")));
-
刪除
- boolean remove(Object obj) :通過元素的equals方法判斷是否是要?jiǎng)h除的那個(gè)元素。只會(huì)刪除找到的第一個(gè)元素
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); collection.remove("AA"); System.out.println(collection);
- boolean removeAll(Collection coll):取當(dāng)前集合的差集
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection); Collection collection2 = new ArrayList(); collection2.add("BB"); collection2.add(123); collection.removeAll(collection2); System.out.println(collection);
-
取兩個(gè)集合的交集
- boolean retainAll(Collection c):把交集的結(jié)果存在當(dāng)前集合中吼野,不影響c
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection); Collection collection2 = new ArrayList(); collection2.add("BB"); collection2.add(123); collection.retainAll(collection2); System.out.println(collection);
-
集合是否相等
- boolean equals(Object obj)
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection); Collection collection2 = new ArrayList(); collection2.addAll(collection); System.out.println(collection.equals(collection2));
-
轉(zhuǎn)成對(duì)象數(shù)組
- Object[] toArray()
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(Arrays.toString(collection.toArray()));
-
獲取集合對(duì)象的哈希值
- hashCode()
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection.hashCode());
-
遍歷
- iterator():返回迭代器對(duì)象添坊,用于集合遍歷
Collection collection = new ArrayList(); collection.add("AA"); collection.add("BB"); collection.add(123); collection.add(new Date()); System.out.println(collection.iterator()); // java.util.ArrayList$Itr@7506e922
使用contains、containsAll箫锤、remove贬蛙、removeAll、retainAll谚攒、equals方法時(shí)阳准,被添加的數(shù)據(jù)對(duì)象所在類需要重寫equals方法。
Iterator迭代器
Iterator迭代器接口
- Iterator對(duì)象稱為迭代器(設(shè)計(jì)模式的一種)馏臭,主要用于遍歷 Collection 集合中的元素野蝇。
- GOF給迭代器模式的定義為:提供一種方法訪問一個(gè)容器(container)對(duì)象中各個(gè)元素讼稚,而又不需暴露該對(duì)象的內(nèi)部細(xì)節(jié)。 迭代器模式绕沈,就是為容器而生锐想。類似于“公交車上的售票員”、“火車上的乘務(wù)員”乍狐、“空姐”赠摇。
-
Collection
接口繼承了java.lang.Iterable
接口,該接口有一個(gè)iterator()方法浅蚪,那么所有實(shí)現(xiàn)了Collection
接口的集合類都有一個(gè)iterator()
方法藕帜,用以返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象。 -
Iterator
僅用于遍歷集合惜傲,Iterator
本身并不提供承裝對(duì)象的能力洽故。如果需要?jiǎng)?chuàng)建Iterator
對(duì)象,則必須有一個(gè)被迭代的集合盗誊。 - 集合對(duì)象每次調(diào)用
iterator()
方法都得到一個(gè)全新的迭代器對(duì)象时甚,默認(rèn)游標(biāo)都在集合的第一個(gè)元素之前。
Iterator接口的方法
返回類型 | 方法 | 描述 |
---|---|---|
boolean |
hasNext() |
如果迭代具有更多元素哈踱,則返回true 撞秋。 |
E |
next() |
返回迭代中的下一個(gè)元素。 |
default void |
remove() |
從底層集合中刪除此迭代器返回的最后一個(gè)元素(可選操作)嚣鄙。 |
在調(diào)用it.next()方法之前必須要調(diào)用it.hasNext()進(jìn)行檢測(cè)吻贿。若不調(diào)用,且下一條記錄無效哑子,直接調(diào)用it.next()會(huì)拋出NoSuchElementException異常舅列。
remove()示例
Iterator iter = coll.iterator();
while(iter.hasNext()){
Object obj = iter.next();
if(obj.equals("Tom")){
iter.remove();
}
}
注意:
Iterator
可以刪除集合的元素,但是是遍歷過程中通過迭代器對(duì)象的remove
方法卧蜓,不是集合對(duì)象的remove
方法帐要。- 如果還未調(diào)用
next()
或在上一次調(diào)用next
方法之后已經(jīng)調(diào)用了remove
方法,再調(diào)用remove
都會(huì)報(bào)IllegalStateException
弥奸。
遍歷Collection元素
Collection collection = new ArrayList();
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
方式一:使用next()方法
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
方式二:使用for循環(huán)
for (int i = 0; i < collection.size(); i++) {
System.out.println(iterator.next());
}
方式三:使用while循環(huán)
// hasNext():判斷是否還有下一個(gè)元素
while (iterator.hasNext()) {
// next():①指針下移 ②將下移以后集合位置上的元素返回
System.out.println(iterator.next());
}
方式四:使用foreach循環(huán)
// 內(nèi)部調(diào)用迭代器
for (Object object : collection) {
System.out.println(object);
}
List接口
- 鑒于Java中數(shù)組用來存儲(chǔ)數(shù)據(jù)的局限性榨惠,我們通常使用List替代數(shù)組
-
List
集合類中 元素有序、且可重復(fù)盛霎,集合中的每個(gè)元素都有其對(duì)應(yīng)的順序索引赠橙。 -
List
容器中的元素都對(duì)應(yīng)一個(gè)整數(shù)型的序號(hào)記載其在容器中的位置,可以根據(jù)序號(hào)存取容器中的元素愤炸。 -
JDK API
中List
接口的實(shí)現(xiàn)類常用的有:ArrayList
期揪、LinkedList
和Vector
。
方法
List
除了從Collection
集合繼承的方法外规个,List
集合里添加了一些根據(jù)索引來操作集合元素的方法凤薛。
-
void add(int index, Object ele)
: 在index
位置插入ele
元素 -
boolean addAll(int index, Collection eles)
: 從index
位置開始將eles
中的所有元素添加進(jìn)來 -
Object get(int index)
: 獲取指定index
位置的元素 -
int indexOf(Object obj)
: 返回obj
在集合中首次出現(xiàn)的位置 -
int lastIndexOf(Object obj)
: 返回obj
在當(dāng)前集合中末次出現(xiàn)的位置 -
Object remove(int index)
: 移除指定index
位置的元素姓建,并返回此元素 -
Object set(int index, Object ele)
: 設(shè)置指定index
位置的元素為ele
-
List subList(int fromIndex, int toIndex)
: 返回從fromIndex
到toIndex
位置的子集合
實(shí)現(xiàn)類
|----List接口
|----ArrayList實(shí)現(xiàn)類:作為L(zhǎng)ist接口的主要實(shí)現(xiàn)類;線程不安全缤苫,效率高速兔;底層使用`Object[] elementData`存儲(chǔ)
|----LinkedList實(shí)現(xiàn)類:底層使用雙向鏈表存儲(chǔ);適用于`頻繁插入活玲、刪除操作`涣狗,操作效率比`ArrayList`高
|----Vector實(shí)現(xiàn)類:List接口的古老實(shí)現(xiàn)類;線程安全翼虫,效率低屑柔;底層使用`Object[] elementData`存儲(chǔ)
ArrayList實(shí)現(xiàn)類
-
ArrayList
是List
接口的典型實(shí)現(xiàn)類屡萤、主要實(shí)現(xiàn)類 - 本質(zhì)上珍剑,
ArrayList
是對(duì)象引用的一個(gè)”變長(zhǎng)”數(shù)組 -
ArrayList
的JDK1.8 之前與之后的實(shí)現(xiàn)區(qū)別?- JDK1.7:
ArrayList
像餓漢式死陆,直接創(chuàng)建一個(gè)初始容量為10的數(shù)組 - JDK1.8:
ArrayList
像懶漢式招拙,一開始創(chuàng)建一個(gè)長(zhǎng)度為0的數(shù)組,當(dāng)添加第一個(gè)元素時(shí)再創(chuàng)建一個(gè)始容量為10的數(shù)組
- JDK1.7:
-
Arrays.asList(…)
方法返回的List
集合措译,既不是ArrayList
實(shí)例别凤,也不是Vector
實(shí)例。Arrays.asList(…)
返回值是一個(gè)固定長(zhǎng)度的List
集合.
LinkedList實(shí)現(xiàn)類
對(duì)于頻繁的插入或刪除元素的操作领虹,建議使用LinkedList
類规哪,效率較高。
LinkedList
內(nèi)部使用雙向鏈表塌衰,沒有聲明數(shù)組诉稍,而是定義了Node
類型的first
和last
,用于記錄首末元素最疆。同時(shí)杯巨,定義內(nèi)部類Node
,作為LinkedList
中保存數(shù)據(jù)的基本結(jié)構(gòu)努酸。Node
除了保存數(shù)據(jù)服爷,還定義了兩個(gè)變量:
-
prev
變量記錄前一個(gè)元素的位置 -
next
變量記錄下一個(gè)元素的位置
新增方法:
- void addFirst(Object obj)
- void addLast(Object obj)
- Object getFirst()
- Object getLast()
- Object removeFirst()
- Object removeLast()
Vector實(shí)現(xiàn)類
Vector
是一個(gè)古老的集合,JDK1.0就有了获诈。大多數(shù)操作與ArrayList
相同仍源,區(qū)別之處在于Vector
是線程安全的。在各種
list
中舔涎,最好把ArrayList
作為缺省選擇镜会。當(dāng)插入、刪除頻繁時(shí)终抽,使用LinkedList
戳表;Vector
總是比ArrayList
慢桶至,所以盡量避免使用。
新增方法:
- void addElement(Object obj)
- void insertElementAt(Object obj,int index)
- void setElementAt(Object obj,int index)
- void removeElement(Object obj)
- void removeAllElements()
Set接口
-
Set
接口是Collection
的子接口匾旭,set
接口沒有提供額外的方法 -
Set
集合不允許包含相同的元素镣屹,如果試把兩個(gè)相同的元素加入同一個(gè)Set
集合中,則添加操作失敗价涝。 -
Set
判斷兩個(gè)對(duì)象是否相同不是使用==
運(yùn)算符女蜈,而是根據(jù)equals()
方法
實(shí)現(xiàn)類
|----Set接口
|----HashSet實(shí)現(xiàn)類:作為Set接口的主要實(shí)現(xiàn)類;線程不安全色瘩;可以存儲(chǔ)null值
|----LinkedHashSet實(shí)現(xiàn)類:作為HashSet的子類伪窖;遍歷其內(nèi)部數(shù)據(jù)時(shí),可以按照添加的順序遍歷居兆;對(duì)于頻繁的遍歷操作覆山,LinkedHashSet效率高于HashSet
|----SortedSet接口
|----TreeSet實(shí)現(xiàn)類:可以按照添加**對(duì)象的指定屬性**進(jìn)行排序;
HashSet實(shí)現(xiàn)類
向HashSet
中添加元素的過程:
- 當(dāng)向
HashSet
集合中存入一個(gè)元素時(shí)泥栖,HashSet
會(huì)調(diào)用該對(duì)象的hashCode()
方法來得到該對(duì)象的hashCode
值簇宽,然后根據(jù)hashCode
值,通過某種散列函數(shù)決定該對(duì)象在HashSet
底層數(shù)組中的存儲(chǔ)位置吧享。(這個(gè)散列函數(shù)會(huì)與底層數(shù)組的長(zhǎng)度相計(jì)算得到在數(shù)組中的下標(biāo)魏割,并且這種散列函數(shù)計(jì)算還盡可能保證能均勻存儲(chǔ)元素,越是散列分布钢颂,該散列函數(shù)設(shè)計(jì)的越好) - 如果兩個(gè)元素的
hashCode()
值相等钞它,會(huì)再繼續(xù)調(diào)用equals
方法,如果equals
方法結(jié)果為true
殊鞭,添加失斣舛狻;如果為false
钱豁,那么會(huì)保存該元素耻卡,但是該數(shù)組的位置已經(jīng)有元素了,那么會(huì)通過鏈表的方式繼續(xù)鏈接牲尺。
如果兩個(gè)元素的equals()
方法返回true
卵酪,但它們的hashCode()
返回值不相等,hashSet
將會(huì)把它們存儲(chǔ)在不同的位置谤碳,但依然可以添加成功溃卡。
底層也是數(shù)組,初始容量為16蜒简,當(dāng)如果使用率超過0.75瘸羡,(16*0.75=12)就會(huì)擴(kuò)大容量為原來的2倍。(16擴(kuò)容為32搓茬,依次為64,128....等)
重寫hashCode()
方法的基本原則
- 在程序運(yùn)行時(shí)犹赖,同一個(gè)對(duì)象多次調(diào)用
hashCode()
方法應(yīng)該返回相同的值队他。 - 當(dāng)兩個(gè)對(duì)象的
equals()
方法比較返回true
時(shí),這兩個(gè)對(duì)象的hashCode()
方法的返回值也應(yīng)相等峻村。 - 對(duì)象中用作
equals()
方法比較的Field麸折,都應(yīng)該用來計(jì)算hashCode
值。
問題:為什么用Eclipse/IDEA復(fù)寫
hashCode
方法粘昨,有31這個(gè)數(shù)字垢啼?
- 選擇系數(shù)的時(shí)候要選擇盡量大的系數(shù)。因?yàn)槿绻?jì)算出來的
hash
地址越大张肾,所謂的“沖突”就越少芭析,查找起來效率也會(huì)提高。(減少?zèng)_突)31
只占用5bits
吞瞪,相乘造成數(shù)據(jù)溢出的概率較小馁启。31
可以由i*31==(i<<5)-1
來表示,現(xiàn)在很多虛擬機(jī)里面都有做相關(guān)優(yōu)化。(提高算法效率)31
是一個(gè)素?cái)?shù)尸饺,素?cái)?shù)作用就是进统,如果我用一個(gè)數(shù)字來乘以這個(gè)素?cái)?shù)助币,那么最終出來的結(jié)果只能被素?cái)?shù)本身和被乘數(shù)還有1來整除浪听!(減少?zèng)_突)
重寫equals()
方法的基本原則
復(fù)寫equals
方法的時(shí)候一般都需要同時(shí)復(fù)寫hashCode
方法。通常參與計(jì)算hashCode
的對(duì)象的屬性也應(yīng)該參與到equals()
眉菱。
LinkedHashSet實(shí)現(xiàn)類
-
LinkedHashSet
是HashSet
的子類 -
LinkedHashSet
根據(jù)元素的hashCode
值來決定元素的存儲(chǔ)位置迹栓,但它同時(shí)使用雙向鏈表維護(hù)元素的次序,這使得元素看起來是以插入順序保存的俭缓。 -
LinkedHashSet
插入性能略低于HashSet
克伊,但在迭代訪問Set
里的全部元素時(shí)有很好的性能。 -
LinkedHashSet
不允許集合元素重復(fù)华坦。
LinkedHashSet中每個(gè)元素都是被鏈表的Node節(jié)點(diǎn)包裝的愿吹,節(jié)點(diǎn)中包含指向上一個(gè)節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)的指針。
TreeSet實(shí)現(xiàn)類
-
TreeSet
是SortedSet
接口的實(shí)現(xiàn)類惜姐,TreeSet
可以確保集合元素處于排序狀態(tài)犁跪。 -
TreeSet
底層使用紅黑結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)。 - 向
TreeSet
中添加的數(shù)據(jù)歹袁,要求是相同類的對(duì)象
新增的方法:
- Comparator comparator()
- Object first()
- Object last()
- Object lower(Object e)
- Object higher(Object e)
- SortedSet subSet(fromElement, toElement)
- SortedSet headSet(toElement)
- SortedSet tailSet(fromElement)
TreeSet
和后面要講的TreeMap
采用紅黑樹的存儲(chǔ)結(jié)構(gòu)坷衍。特點(diǎn):有序,查詢速度比List
快条舔。
兩種排序方法:自然排序和定制排序枫耳。默認(rèn)情況下,TreeSet
采用自然排序孟抗。
自然排序
TreeSet
會(huì)調(diào)用集合元素的compareTo(Object obj)
方法來比較元素之間的大小關(guān)系迁杨,然后將集合元素按升序(默認(rèn)情況)排列-
<span style="color:red;">如果試圖把一個(gè)對(duì)象添加到
TreeSet
時(shí)钻心,則該對(duì)象的類必須實(shí)現(xiàn)Comparable
接口。</span>- 實(shí)現(xiàn)
Comparable
的類必須實(shí)現(xiàn)compareTo(Object obj)
方法铅协,兩個(gè)對(duì)象即通過compareTo(Object obj)
方法的返回值來比較大小扔役。
- 實(shí)現(xiàn)
-
Comparable
的典型實(shí)現(xiàn)-
BigDecimal
、BigInteger
以及所有的數(shù)值型對(duì)應(yīng)的包裝類:按它們對(duì)應(yīng)的數(shù)值大小進(jìn)行比較 -
Character
:按字符的unicode`值來進(jìn)行比較 -
Boolean
:true
對(duì)應(yīng)的包裝類實(shí)例大于false
對(duì)應(yīng)的包裝類實(shí)例 -
String
:按字符串中字符的unicode
值進(jìn)行比較 -
Date
警医、Time
:后邊的時(shí)間亿胸、日期比前面的時(shí)間、日期大
-
向
TreeSet
中添加元素時(shí)预皇,只有第一個(gè)元素?zé)o須比較compareTo()
方法侈玄,后面添加的所有元素都會(huì)調(diào)用compareTo()
方法進(jìn)行比較。<span style="color:red;">因?yàn)橹挥邢嗤惖膬蓚€(gè)實(shí)例才會(huì)比較大小吟温,所以向
TreeSet
中添加的應(yīng)該是同一個(gè)類的對(duì)象序仙。</span>對(duì)于
TreeSet
集合 而言,它判斷兩個(gè)對(duì)象是否相等的唯一標(biāo)準(zhǔn)是:兩個(gè)對(duì)象通過compareTo(Object obj)
方法比較返回值鲁豪。當(dāng)需要把一個(gè)對(duì)象放入
TreeSet
中潘悼,重寫該對(duì)象對(duì)應(yīng)的equals()
方法時(shí),應(yīng)保證該方法與compareTo(Object obj)
方法有一致的結(jié)果:如果兩個(gè)對(duì)象通過equals()
方法比較返回true
爬橡,則通過compareTo(Object obj)
方法比較應(yīng)返回0治唤。否則,讓人難以理解糙申。
// User類宾添,實(shí)現(xiàn)Comparable接口,用于TreeSet添加時(shí)進(jìn)行比較
public class User implements Comparable {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
// 按姓名由小到大柜裸,年齡由小到大排列
@Override
public int compareTo(Object o) {
if (o instanceof User) {
User another = (User) o;
int compareTo = this.name.compareTo(another.name);
if (compareTo != 0) {
return compareTo;
} else {
return Integer.compare(this.age, another.age);
}
} else {
throw new RuntimeException("類型不匹配");
}
}
}
@Test
public void testTreeSet() {
TreeSet treeSet = new TreeSet();
treeSet.add(new User("Tom", 12));
treeSet.add(new User("Jerry", 23));
treeSet.add(new User("Kim", 16));
treeSet.add(new User("Mary", 24));
treeSet.add(new User("Rose", 12));
treeSet.add(new User("Kim", 13));
for (Object object : treeSet) {
System.out.println(object);
}
}
輸出:
User [name=Jerry, age=23]
User [name=Kim, age=13]
User [name=Kim, age=16]
User [name=Mary, age=24]
User [name=Rose, age=12]
User [name=Tom, age=12]
定制排序
-
TreeSet
的自然排序要求元素所屬的類實(shí)現(xiàn)Comparable
接口缕陕,如果元素所屬的類沒有實(shí)現(xiàn)Comparable
接口,或不希望按照升序(默認(rèn)情況)的方式排列元素或希望按照其它屬性大小進(jìn)行排序疙挺,則考慮使用定制排序扛邑。定制排序,通過Comparator
接口來實(shí)現(xiàn)铐然。需要重寫compare(T o1,T o2)
方法蔬崩。 - 利用
int compare(T o1,T o2)
方法,比較o1
和o2
的大薪蹙簟:如果方法返回正整數(shù)舱殿,則表示o1
大于o2
;如果返回0险掀,表示相等沪袭;返回負(fù)整數(shù),表示o1
小于o2
。 - 要實(shí)現(xiàn)定制排序冈绊,需要將實(shí)現(xiàn)
Comparator
接口的實(shí)例作為形參傳遞給TreeSet
的構(gòu)造器侠鳄。 - 此時(shí),仍然只能向
TreeSet
中添加類型相同的對(duì)象死宣。否則發(fā)生ClassCastException
異常伟恶。 - 使用定制排序判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是:通過
Comparator
比較兩個(gè)元素返回了0。
@Test
public void testTreeSetComparator() {
// 按年齡由大到小排列
Comparator<User> comparator = new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return -Integer.compare(o1.getAge(), o2.getAge());
}
};
TreeSet treeSet = new TreeSet(comparator);
treeSet.add(new User("Tom", 12));
treeSet.add(new User("Jerry", 23));
treeSet.add(new User("Kim", 16));
treeSet.add(new User("Mary", 24));
treeSet.add(new User("Rose", 12));
treeSet.add(new User("Kim", 13));
for (Object object : treeSet) {
System.out.println(object);
}
}
輸出:由于new User("Rose", 12)
與new User("Tom", 12))
的年齡相同毅该,比較的返回值為0博秫,且排在Tom
的后面,就會(huì)認(rèn)為Rose
與Tom
是相同的眶掌,所以沒有添加到TreeSet
中去挡育。
User [name=Mary, age=24]
User [name=Jerry, age=23]
User [name=Kim, age=16]
User [name=Kim, age=13]
User [name=Tom, age=12]
?????????????????????????????????????????????????????????????????????????
自然排序中,比較兩個(gè)對(duì)象是否相同的標(biāo)準(zhǔn)為:compareTo()返回0朴爬,不再是equals()即寒。
定制排序中,比較兩個(gè)對(duì)象是否相同的標(biāo)準(zhǔn)為:compare()返回0召噩,不再是equals()母赵。
?????????????????????????????????????????????????????????????????????????
Map接口
-
Map
與Collection
并列存在。用于保存具有 映射關(guān)系的數(shù)據(jù):key-value
-
Map
中的key
和value
都可以是任何引用類型的數(shù)據(jù) - Map 中的 key 用Set來存放具滴, 不允許重復(fù)凹嘲,即同一個(gè) Map 對(duì)象所對(duì)應(yīng)的類,須重寫hashCode()和equals()方法
- 常用String類作為Map的“鍵”
- key 和 value 之間存在單向一對(duì)一關(guān)系抵蚊,即通過指定的 key 總能找到唯一的施绎、確定的 value
- Map接口的常用實(shí)現(xiàn)類:HashMap溯革、TreeMap贞绳、LinkedHashMap和Properties。其中致稀,HashMap是 Map 接口使用頻率最高的實(shí)現(xiàn)類
繼承結(jié)構(gòu)
|----Map接口:雙列集合
|----HashMap實(shí)現(xiàn)類:作為Map的主要實(shí)現(xiàn)類冈闭;線程不安全,效率高抖单;可以存儲(chǔ)null的key和value萎攒;key所在類要重寫equals()和hashCode();value所在類要重寫equals()
|----LinkedHashMap實(shí)現(xiàn)類:保證在遍歷map元素時(shí)矛绘,可以按照添加的順序?qū)崿F(xiàn)遍歷耍休。原因:在原有的HashMap底層結(jié)構(gòu)上,添加一對(duì)指針货矮,指向前一個(gè)和后一個(gè)元素羊精,對(duì)于頻繁的遍歷操作,此類執(zhí)行效率高于HashMap囚玫。
|----SortedMap接口
|----TreeMap實(shí)現(xiàn)類:保證按照添加的key-value進(jìn)行排序喧锦,實(shí)現(xiàn)排序遍歷读规。考慮key的自然排序或定制排序燃少。底層使用紅黑樹
|----Hashtable實(shí)現(xiàn)類:古老的實(shí)現(xiàn)類束亏;線程安全,效率低阵具;不能存儲(chǔ)null的key和value
|----Properties實(shí)現(xiàn)類:常用來處理配置文件碍遍。key和value都是String類型。
HashMap和Hashtable的關(guān)系類似于ArrayList和Vector的關(guān)系阳液,HashMap和ArrayList要比Hashtable和Vector新雀久,所以后續(xù)使用時(shí),主要使用HashMap和ArrayList趁舀。
Map結(jié)構(gòu)的理解
- Map中的key:無序的赖捌、不可重復(fù)的愧膀,使用Set存儲(chǔ)所有的key --> key所在類要重寫equals()和hashCode()(以HashMap為例)
- Map中的value:無序的权逗、可重復(fù)的,使用Collection存儲(chǔ)所有的value --> value所在的類要重寫equals()
- 一個(gè)鍵值對(duì):key-value構(gòu)成一個(gè)Entry對(duì)象
- Map中的entry:無序的诺舔、不可重復(fù)的奉狈,使用Set存儲(chǔ)所有的entry
常用方法
- 添加卤唉、刪除、修改操作:
-
Object put(Object key,Object value)
:將指定key-value添加到(或修改)當(dāng)前map對(duì)象中 -
void putAll(Map m)
:將m中的所有key-value對(duì)存放到當(dāng)前map中 -
Object remove(Object key)
:移除指定key的key-value對(duì)仁期,并返回value -
void clear()
:清空當(dāng)前map中的所有數(shù)據(jù)
-
- 元素 查詢的操作:
-
Object get(Object key)
:獲取指定key對(duì)應(yīng)的value -
boolean containsKey(Object key)
:是否包含指定的key -
boolean containsValue(Object value)
:是否包含指定的value -
int size()
:返回map中key-value對(duì)的個(gè)數(shù) -
boolean isEmpty()
:判斷當(dāng)前map是否為空 -
boolean equals(Object obj)
:判斷當(dāng)前map和參數(shù)對(duì)象obj是否相等
-
- 元視圖操作的方法:
-
Set keySet()
:返回所有key構(gòu)成的Set集合 -
Collection values()
:返回所有value構(gòu)成的Collection集合 -
Set entrySet()
:返回所有key-value對(duì)構(gòu)成的Set集合
-
實(shí)現(xiàn)類
HashMap實(shí)現(xiàn)類
HashMap
是Map
接口使用頻率最高的實(shí)現(xiàn)類桑驱。允許使用
null
鍵和null
值,與HashSet
一樣跛蛋,不保證映射的順序熬的。所有的
key
構(gòu)成的集合是Set
:無序的、不可重復(fù)的赊级。所以押框,key
所在的類要重寫:equals()
和hashCode()
所有的
value
構(gòu)成的集合是Collection
:無序的、可以重復(fù)的理逊。所以橡伞,value
所在的類要重寫:equals()
一個(gè)
key-value
構(gòu)成一個(gè)entry
所有的
entry
構(gòu)成的集合是Set
:無序的、不可重復(fù)的HashMap
判斷兩個(gè)key
相等的標(biāo)準(zhǔn)是:兩個(gè)key
通過equals()
方法返回true
晋被,hashCode
值也相等兑徘。HashMap
判斷兩個(gè)value
相等的標(biāo)準(zhǔn)是:兩個(gè)value
通過equals()
方法返回true
。
HashMap的存儲(chǔ)結(jié)構(gòu)
JDK 7及以前版本:HashMap是數(shù)組+鏈表結(jié)構(gòu)(即為鏈地址法)羡洛。
HashMap
的內(nèi)部存儲(chǔ)結(jié)構(gòu)其實(shí)是數(shù)組和鏈表的結(jié)合挂脑。當(dāng)實(shí)例化一個(gè)HashMap時(shí),系統(tǒng)會(huì)創(chuàng)建一個(gè)長(zhǎng)度為Capacity
的Entry
數(shù)組,這個(gè)長(zhǎng)度在哈希表中被稱為容量(Capacity
)最域,在這個(gè)數(shù)組中可以存放元素的位置我們稱之為“桶”(bucket
)谴分,每個(gè)bucket都有自己的索引,系統(tǒng)可以根據(jù)索引快速的查找bucket
中的元素镀脂。
每個(gè)bucket
中存儲(chǔ)一個(gè)元素牺蹄,即一個(gè)Entry
對(duì)象,但每一個(gè)Entry對(duì)象
可以帶一個(gè)引用變量薄翅,用于指向下一個(gè)元素沙兰,因此,在一個(gè)桶中翘魄,就有可能生成一個(gè)Entry鏈鼎天。而且新添加的元素作為鏈表的head。
添加元素的過程
向HashMap
中添加entry1(key暑竟,value)
斋射,需要首先計(jì)算entry1
中key
的哈希值(根據(jù)key
所在類的hashCode()
計(jì)算得到),此哈希值經(jīng)過處理以后但荤,得到在底層Entry[]
數(shù)組中要存儲(chǔ)的位置i
罗岖。如果位置i
上沒有元素,則entry1
直接添加成功腹躁。如果位置i
上已經(jīng)存在entry2
(或還有鏈表存在的entry3
桑包,entry4
),則需要通過循環(huán)的方法纺非,依次比較entry1
中key
和其他的entry
哑了。如果彼此hash值
不同,則直接添加成功烧颖。如果hash
值不同弱左,繼續(xù)比較二者是否equals
。如果返回值為true
倒信,則使用entry1
的value
去替換equals
為true
的entry
的value
科贬。如果遍歷一遍以后,發(fā)現(xiàn)所有的equals
返回都為false
,則entry1
仍可添加成功鳖悠。entry1
指向原有的entry
元素。
HashMap的擴(kuò)容
當(dāng)HashMap
中的元素越來越多的時(shí)候优妙,hash
沖突的幾率也就越來越高乘综,因?yàn)閿?shù)組的長(zhǎng)度是固定的。所以為了提高查詢的效率套硼,就要對(duì)HashMap
的數(shù)組進(jìn)行擴(kuò)容卡辰,而在HashMap
數(shù)組擴(kuò)容之后,最消耗性能的點(diǎn)就出現(xiàn)了:原數(shù)組中的數(shù)據(jù)必須重新計(jì)算其在新數(shù)組中的位置,并放進(jìn)去九妈,這就是resize
反砌。
HashMap的擴(kuò)容時(shí)機(jī)
當(dāng)HashMap
中的元素個(gè)數(shù)超過數(shù)組大小(數(shù)組總大小length
,不是數(shù)組中個(gè)數(shù)size
)loadFactor
*時(shí),就會(huì)進(jìn)行數(shù)組擴(kuò)容萌朱,loadFactor
的默認(rèn)值(DEFAULT_LOAD_FACTOR
)為0.75
宴树,這是一個(gè)折中的取值。也就是說晶疼,默認(rèn)情況下酒贬,數(shù)組大小(DEFAULT_INITIAL_CAPACITY
)為16
,那么當(dāng)HashMap
中元素個(gè)數(shù)超過16*0.75=12
(這個(gè)值就是代碼中的threshold
值翠霍,也叫做臨界值)的時(shí)候锭吨,就把數(shù)組的大小擴(kuò)展為2*16=32
,即擴(kuò)大一倍寒匙,然后重新計(jì)算每個(gè)元素在數(shù)組中的位置零如,而這是一個(gè)非常消耗性能的操作,所以如果我們已經(jīng)預(yù)知HashMap
中元素的個(gè)數(shù)锄弱,那么預(yù)設(shè)元素的個(gè)數(shù)能夠有效的提高HashMap
的性能埠况。
簡(jiǎn)述HashMap map = new HashMap();
的過程:
實(shí)例化后,底層創(chuàng)建了長(zhǎng)度是16的一維數(shù)組Entry[] table
棵癣。
調(diào)用map.put(key1, value1)
存放元素時(shí):首先辕翰,調(diào)用key1
所在類的hashCode()
計(jì)算key1
的哈希值,此哈希值經(jīng)過某種算法計(jì)算以后狈谊,得到在Entry
數(shù)組中的存放位置喜命。
- 如果此位置上的數(shù)據(jù)為空,此時(shí)
key1-value1
添加成功 - 如果此位置上的數(shù)據(jù)不為空(意味著此位置上存在一個(gè)或多個(gè)數(shù)據(jù)(以鏈表形式存在))河劝,比較
key1
和已經(jīng)存在的一個(gè)或多個(gè)數(shù)據(jù)的哈希值:- 如果
key1
的哈希值與已經(jīng)存在的數(shù)據(jù)的哈希值都不相同壁榕,此時(shí)key1-value1
添加成功。 - 如果
key1
的哈希值和已經(jīng)存在的某一個(gè)數(shù)據(jù)(key2-value2
)的哈希值相同赎瞎,繼續(xù)比較:調(diào)用key1所在類的equals()
方法牌里,進(jìn)行比較:- 如果
equals()
返回false
:此時(shí)key1-value1
添加成功。 - 如果
equals()
返回true
:使用value1
替換value2
值务甥。
- 如果
- 如果
擴(kuò)容方式:擴(kuò)容為原來容量的2倍牡辽,并將原有的數(shù)據(jù)復(fù)制過來。
JDK 8版本發(fā)布以后:HashMap是數(shù)組+鏈表+紅黑樹實(shí)現(xiàn)敞临。
HashMap
的內(nèi)部存儲(chǔ)結(jié)構(gòu)其實(shí)是數(shù)組+鏈表+樹
的結(jié)合态辛。當(dāng)實(shí)例化一個(gè)HashMap
時(shí),會(huì)初始化initialCapacity
和loadFactor
挺尿,在put
第一對(duì)映射關(guān)系時(shí)奏黑,系統(tǒng)會(huì)創(chuàng)建一個(gè)長(zhǎng)度為initialCapacity
的Node
數(shù)組炊邦,這個(gè)長(zhǎng)度在哈希表
中被稱為容量(Capacity
),在這個(gè)數(shù)組中可以存放元素的位置我們稱之為“桶”(bucket
)熟史,每個(gè)bucket
都有自己的索引馁害,系統(tǒng)可以根據(jù)索引快速的查找bucket
中的元素。
每個(gè)bucket
中存儲(chǔ)一個(gè)元素蹂匹,即一個(gè)Node
對(duì)象碘菜,但每一個(gè)Node
對(duì)象可以帶一個(gè)引用變量next
,用于指向下一個(gè)元素怒详,因此炉媒,在一個(gè)桶中,就有可能生成一個(gè)Node
鏈昆烁。也可能是一個(gè)一個(gè)TreeNode
對(duì)象吊骤,每一個(gè)TreeNode
對(duì)象可以有兩個(gè)葉子結(jié)點(diǎn)left
和right
,因此静尼,在一個(gè)桶中白粉,就有可能生成一個(gè)TreeNode
樹。而新添加的元素作為鏈表的last
鼠渺,或樹的葉子結(jié)點(diǎn)鸭巴。
HashMap進(jìn)行擴(kuò)容和樹形化的時(shí)機(jī)
當(dāng)HashMap中的元素個(gè)數(shù)超過數(shù)組大小(數(shù)組總大小length,不是數(shù)組中個(gè)數(shù)size)loadFactor
*時(shí),就會(huì)進(jìn)行數(shù)組擴(kuò)容拦盹,loadFactor
的默認(rèn)值(DEFAULT_LOAD_FACTOR
)為0.75
鹃祖,這是一個(gè)折中的取值。也就是說普舆,默認(rèn)情況下恬口,數(shù)組大小(DEFAULT_INITIAL_CAPACITY
)為16
,那么當(dāng)HashMap中元素個(gè)數(shù)超過16*0.75=12
(這個(gè)值就是代碼中的threshold
值沼侣,也叫做臨界值)的時(shí)候祖能,就把數(shù)組的大小擴(kuò)展為2*16=32
,即擴(kuò)大一倍蛾洛,然后重新計(jì)算每個(gè)元素在數(shù)組中的位置养铸,而這是一個(gè)非常消耗性能的操作,所以如果我們已經(jīng)預(yù)知HashMap
中元素的個(gè)數(shù)轧膘,那么預(yù)設(shè)元素的個(gè)數(shù)能夠有效的提高HashMap
的性能钞螟。
當(dāng)HashMap
中的其中一個(gè)鏈的對(duì)象個(gè)數(shù)如果達(dá)到了8
個(gè),此時(shí)如果capacity
沒有達(dá)到64
扶供,那么HashMap
會(huì)先擴(kuò)容解決筛圆,如果已經(jīng)達(dá)到了64
,那么這個(gè)鏈會(huì)變成樹椿浓,結(jié)點(diǎn)類型由Node
變成TreeNode
類型太援。當(dāng)然,如果當(dāng)映射關(guān)系被移除后扳碍,下次resize
方法時(shí)判斷樹的結(jié)點(diǎn)個(gè)數(shù)低于6
個(gè)提岔,也會(huì)把樹再轉(zhuǎn)為鏈表。
對(duì)比JDK 7和JDK 8
-
HashMap map = new HashMap();
//默認(rèn)情況下笋敞,先不創(chuàng)建長(zhǎng)度為16的數(shù)組 - 當(dāng)首次調(diào)用
map.put()
時(shí)碱蒙,再創(chuàng)建長(zhǎng)度為16的數(shù)組 - 數(shù)組為
Node
類型,在jdk7中稱為Entry
類型 - 形成鏈表結(jié)構(gòu)時(shí)夯巷,新添加的
key-value
對(duì)在鏈表的尾部(七上八下) - 當(dāng)數(shù)組指定索引位置的鏈表長(zhǎng)度>8時(shí)赛惩,且map中的數(shù)組的長(zhǎng)度>64時(shí),此索引位置上的所有
key-value
對(duì)使用紅黑樹進(jìn)行存儲(chǔ)
LinkedHashMap實(shí)現(xiàn)類
LinkedHashMap
是HashMap的子類在
HashMap
存儲(chǔ)結(jié)構(gòu)的基礎(chǔ)上趁餐,使用了一對(duì)雙向鏈表來記錄添加元素的順序與
LinkedHashSet
類似喷兼,LinkedHashMap
可以維護(hù)Map
的迭代順序:迭代順序與Key-Value
對(duì)的插入順序一致
HashMap中的內(nèi)部類:Node
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
}
LinkedHashMap中的內(nèi)部類:Entry
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
TreeMap實(shí)現(xiàn)類
-
TreeMap
存儲(chǔ)Key-Value
對(duì)時(shí),需要根據(jù)key-value
對(duì)進(jìn)行排序后雷。TreeMap
可以保證所有的Key-Value
對(duì)處于有序狀態(tài)季惯。 -
TreeSet
底層使用紅黑樹結(jié)構(gòu)存儲(chǔ)數(shù)據(jù) -
TreeMap
的Key
的排序:- 自然排序:
TreeMap
的所有的Key
必須實(shí)現(xiàn)Comparable
接口,而且所有的Key
應(yīng)該是同一個(gè)類的對(duì)象臀突,否則將會(huì)拋出ClasssCastException
- 定制排序:創(chuàng)建
TreeMap
時(shí)勉抓,傳入一個(gè)Comparator
對(duì)象,該對(duì)象負(fù)責(zé)對(duì)TreeMap
中的所有key
進(jìn)行排序候学。此時(shí)不需要Map
的Key
實(shí)現(xiàn)Comparable
接口
- 自然排序:
-
TreeMap
判斷兩個(gè)key
相等的標(biāo)準(zhǔn):兩個(gè)key
通過compareTo()
方法或者compare()
方法返回0
藕筋。
Hashtable實(shí)現(xiàn)類(古老)
-
Hashtable
是個(gè)古老的Map
實(shí)現(xiàn)類,JDK1.0就提供了梳码。不同于HashMap
隐圾,Hashtable
是線程安全的。 -
Hashtable
實(shí)現(xiàn)原理和HashMap
相同边翁,功能相同翎承。底層都使用哈希表結(jié)構(gòu),查詢速度快符匾,很多情況下可以互用叨咖。 - 與
HashMap
不同,Hashtable
不允許使用null
作為key
和value
- 與
HashMap
一樣啊胶,Hashtable
也不能保證其中Key-Value
對(duì)的順序 -
Hashtable
判斷兩個(gè)key
相等甸各、兩個(gè)value
相等的標(biāo)準(zhǔn),與HashMap
一致焰坪。
Properties實(shí)現(xiàn)類
-
Properties
類是Hashtable
的子類趣倾,該對(duì)象用于處理屬性文件 - 由于屬性文件里的
key
、value
都是字符串類型某饰,所以Properties
里的key
和value
都是字符串類型 - 存取數(shù)據(jù)時(shí)儒恋,建議使用
setProperty(String key,String value)
方法和getProperty(String key)
方法
例:
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);
Collections工具類
Collections
是一個(gè)操作Set
善绎、List
和Map
等集合的工具類Collections
中提供了一系列靜態(tài)的方法對(duì)集合元素進(jìn)行排序、查詢和修改等操作诫尽,還提供了對(duì)集合對(duì)象設(shè)置不可變禀酱、對(duì)集合對(duì)象實(shí)現(xiàn)同步控制等方法-
排序操作:為(均為static方法)
-
reverse(List)
:反轉(zhuǎn)List
中元素的順序 -
shuffle(List)
:對(duì)List
集合元素進(jìn)行隨機(jī)排序 -
sort(List)
:根據(jù)元素的自然順序?qū)χ付?code>List集合元素按升序排序 -
sort(List,Comparator)
:根據(jù)指定的Comparator
產(chǎn)生的順序?qū)?code>List集合元素進(jìn)行排序 -
swap(List牧嫉,int剂跟,int)
:將指定list
集合中的i處元素和j處元素進(jìn)行交換
-
-
查找、替換:
-
Object max(Collection)
:根據(jù)元素的自然順序酣藻,返回給定集合中的最大元素 -
Object max(Collection曹洽,Comparator)
:根據(jù)Comparator
指定的順序,返回給定集合中的最大元素 Object min(Collection)
Object min(Collection辽剧,Comparator)
-
int frequency(Collection送淆,Object)
:返回指定集合中指定元素的出現(xiàn)次數(shù) -
void copy(List dest,List src)
:將src
中的內(nèi)容復(fù)制到dest
中 -
boolean replaceAll(List list,Object oldVal抖仅,Object newVal)
:使用新值替換List
對(duì)象的所有舊值
-
-
同步控制:
Collections
類中提供了多個(gè)synchronizedXxx()
方法坊夫,該方法可使將指定集合包裝成線程同步的集合,從而可以解決多線程并發(fā)訪問集合時(shí)的線程安全問題