一、Java集合類(lèi)簡(jiǎn)介:
Java集合大致可以分為Set氏仗、List吉捶、Queue和Map四種體系夺鲜。
其中Set代表無(wú)序、不可重復(fù)的集合呐舔;List代表有序币励、重復(fù)的集合;而Map則代表具有映射關(guān)系的集合珊拼。Java 5 又增加了Queue體系集合食呻,代表一種隊(duì)列集合實(shí)現(xiàn)。
Java集合就像一種容器澎现,可以把多個(gè)對(duì)象(實(shí)際上是對(duì)象的引用仅胞,但習(xí)慣上都稱(chēng)對(duì)象)“丟進(jìn)”該容器中。從Java 5 增加了泛型以后剑辫,Java集合可以記住容器中對(duì)象的數(shù)據(jù)類(lèi)型干旧,使得編碼更加簡(jiǎn)潔、健壯妹蔽。
1.Java集合和數(shù)組的區(qū)別:
①.數(shù)組長(zhǎng)度在初始化時(shí)指定椎眯,意味著只能保存定長(zhǎng)的數(shù)據(jù)。而集合可以保存數(shù)量不確定的數(shù)據(jù)胳岂。同時(shí)可以保存具有映射關(guān)系的數(shù)據(jù)(即關(guān)聯(lián)數(shù)組编整,鍵值對(duì) key-value)。
②.數(shù)組元素即可以是基本類(lèi)型的值旦万,也可以是對(duì)象闹击。集合里只能保存對(duì)象(實(shí)際上只是保存對(duì)象的引用變量),基本數(shù)據(jù)類(lèi)型的變量要轉(zhuǎn)換成對(duì)應(yīng)的包裝類(lèi)才能放入集合類(lèi)中成艘。
2.Java集合類(lèi)之間的繼承關(guān)系:
Java的集合類(lèi)主要由兩個(gè)接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口赏半。
圖中,ArrayList,HashSet,LinkedList,TreeSet是我們經(jīng)常會(huì)有用到的已實(shí)現(xiàn)的集合類(lèi)淆两。
Map實(shí)現(xiàn)類(lèi)用于保存具有映射關(guān)系的數(shù)據(jù)断箫。Map保存的每項(xiàng)數(shù)據(jù)都是key-value對(duì),也就是由key和value兩個(gè)值組成秋冰。Map里的key是不可重復(fù)的仲义,key用戶(hù)標(biāo)識(shí)集合里的每項(xiàng)數(shù)據(jù)。
圖中剑勾,HashMap埃撵,TreeMap是我們經(jīng)常會(huì)用到的集合類(lèi)。
二虽另、Collection接口:
1.簡(jiǎn)介
Collection接口是Set,Queue,List的父接口暂刘。Collection接口中定義了多種方法可供其子類(lèi)進(jìn)行實(shí)現(xiàn),以實(shí)現(xiàn)數(shù)據(jù)操作捂刺。由于方法比較多谣拣,就偷個(gè)懶募寨,直接把JDK文檔上的內(nèi)容搬過(guò)來(lái)。
1.1.接口中定義的方法
可以看出Collection用法有:添加元素森缠,刪除元素拔鹰,返回Collection集合的個(gè)數(shù)以及清空集合等。
其中重點(diǎn)介紹iterator()方法贵涵,該方法的返回值是Iterator<E>列肢。
1.2.使用Iterator遍歷集合元素
Iterator接口經(jīng)常被稱(chēng)作迭代器,它是Collection接口的父接口独悴。但I(xiàn)terator主要用于遍歷集合中的元素例书。
Iterator接口中主要定義了2個(gè)方法:
下面程序簡(jiǎn)單示范了通過(guò)Iterator對(duì)象逐個(gè)獲取元素的邏輯锣尉。
public class IteratorExample {
public static void main(String[] args){
//創(chuàng)建集合刻炒,添加元素
Collection<Day> days = new ArrayList<Day>();
for(int i =0;i<10;i++){
Day day = new Day(i,i*60,i*3600);
days.add(day);
}
//獲取days集合的迭代器
Iterator<Day> iterator = days.iterator();
while(iterator.hasNext()){//判斷是否有下一個(gè)元素
Day next = iterator.next();//取出該元素
//逐個(gè)遍歷,取得元素后進(jìn)行后續(xù)操作
.....
}
}
}
注意: 當(dāng)使用Iterator對(duì)集合元素進(jìn)行迭代時(shí)自沧,把集合元素的值傳給了迭代變量(就如同參數(shù)傳遞是值傳遞坟奥,基本數(shù)據(jù)類(lèi)型傳遞的是值,引用類(lèi)型傳遞的僅僅是對(duì)象的引用變量拇厢。
下面的程序演示了這一點(diǎn):
public class IteratorExample {
public static void main(String[] args) {
List<MyObject> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new MyObject(i));
}
System.out.println(list.toString());
Iterator<MyObject> iterator = list.iterator();//集合元素的值傳給了迭代變量爱谁,僅僅傳遞了對(duì)象引用。保存的僅僅是指向?qū)ο髢?nèi)存空間的地址
while (iterator.hasNext()) {
MyObject next = iterator.next();
next.num = 99;
}
System.out.println(list.toString());
}
static class MyObject {
int num;
MyObject(int num) {
this.num = num;
}
@Override
public String toString() {
return String.valueOf(num);
}
}
}
輸出結(jié)果如下:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
下面具體介紹Collection接口的三個(gè)子接口Set孝偎,List访敌,Queue。
2.Set集合
簡(jiǎn)介
Set集合與Collection集合基本相同衣盾,沒(méi)有提供任何額外的方法寺旺。實(shí)際上Set就是Collection,只是行為略有不同(Set不允許包含重復(fù)元素)势决。
Set集合不允許包含相同的元素阻塑,如果試圖把兩個(gè)相同的元素加入同一個(gè)Set集合中,則添加操作失敗果复,add()方法返回false陈莽,且新元素不會(huì)被加入。
3.List集合
3.1.簡(jiǎn)介
List集合代表一個(gè)元素有序虽抄、可重復(fù)的集合走搁,集合中每個(gè)元素都有其對(duì)應(yīng)的順序索引。List集合允許使用重復(fù)元素迈窟,可以通過(guò)索引來(lái)訪問(wèn)指定位置的集合元素 私植。List集合默認(rèn)按元素的添加順序設(shè)置元素的索引,例如第一個(gè)添加的元素索引為0菠隆,第二個(gè)添加的元素索引為1......
List作為Collection接口的子接口兵琳,可以使用Collection接口里的全部方法狂秘。而且由于List是有序集合,因此List集合里增加了一些根據(jù)索引來(lái)操作集合元素的方法躯肌。
3.2.接口中定義的方法
void add(int index, Object element): 在列表的指定位置插入指定元素(可選操作)者春。
boolean addAll(int index, Collection<? extends E> c) : 將集合c 中的所有元素都插入到列表中的指定位置index處。
Object get(index): 返回列表中指定位置的元素清女。
int indexOf(Object o): 返回此列表中第一次出現(xiàn)的指定元素的索引钱烟;如果此列表不包含該元素,則返回 -1嫡丙。
int lastIndexOf(Object o): 返回此列表中最后出現(xiàn)的指定元素的索引拴袭;如果列表不包含此元素,則返回 -1曙博。
Object remove(int index): 移除列表中指定位置的元素拥刻。
Object set(int index, Object element): 用指定元素替換列表中指定位置的元素。
List subList(int fromIndex, int toIndex): 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的所有集合元素組成的子集父泳。
Object[] toArray(): 返回按適當(dāng)順序包含列表中的所有元素的數(shù)組(從第一個(gè)元素到最后一個(gè)元素)般哼。
除此之外,Java 8還為L(zhǎng)ist接口添加了如下兩個(gè)默認(rèn)方法惠窄。
void replaceAll(UnaryOperator operator): 根據(jù)operator指定的計(jì)算規(guī)則重新設(shè)置List集合的所有元素蒸眠。
void sort(Comparator c): 根據(jù)Comparator參數(shù)對(duì)List集合的元素排序。
4.Queue集合
4.1.簡(jiǎn)介
Queue用戶(hù)模擬隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)杆融,隊(duì)列通常是指“先進(jìn)先出”(FIFO楞卡,first-in-first-out)的容器。隊(duì)列的頭部是在隊(duì)列中存放時(shí)間最長(zhǎng)的元素脾歇,隊(duì)列的尾部是保存在隊(duì)列中存放時(shí)間最短的元素蒋腮。新元素插入(offer)到隊(duì)列的尾部,訪問(wèn)元素(poll)操作會(huì)返回隊(duì)列頭部的元素介劫。通常徽惋,隊(duì)列不允許隨機(jī)訪問(wèn)隊(duì)列中的元素。
4.2.接口中定義的方法
三座韵、Map集合
1.簡(jiǎn)介
Map用戶(hù)保存具有映射關(guān)系的數(shù)據(jù)险绘,因此Map集合里保存著兩組數(shù),一組值用戶(hù)保存Map里的key,另一組值用戶(hù)保存Map里的value誉碴,key和value都可以是任何引用類(lèi)型的數(shù)據(jù)宦棺。Map的key不允許重復(fù),即同一個(gè)Map對(duì)象的任何兩個(gè)key通過(guò)equals方法比較總是返回false黔帕。
如下圖所描述代咸,key和value之間存在單向一對(duì)一關(guān)系,即通過(guò)指定的key,總能找到唯一的成黄、確定的value呐芥。從Map中取出數(shù)據(jù)時(shí)逻杖,只要給出指定的key,就可以取出對(duì)應(yīng)的value思瘟。
2.Map集合與Set集合荸百、List集合的關(guān)系
①.與Set集合的關(guān)系
如果 把Map里的所有key放在一起看,它們就組成了一個(gè)Set集合(所有的key沒(méi)有順序滨攻,key與key之間不能重復(fù))够话,實(shí)際上Map確實(shí)包含了一個(gè)keySet()方法,用戶(hù)返回Map里所有key組成的Set集合光绕。
②.與List集合的關(guān)系
如果把Map里的所有value放在一起來(lái)看女嘲,它們又非常類(lèi)似于一個(gè)List:元素與元素之間可以重復(fù),每個(gè)元素可以根據(jù)索引來(lái)查找诞帐,只是Map中索引不再使用整數(shù)值欣尼,而是以另外一個(gè)對(duì)象作為索引。
3.接口中定義的方法
Map中還包括一個(gè)內(nèi)部類(lèi)Entry景埃,該類(lèi)封裝了一個(gè)key-value對(duì)媒至。Entry包含如下三個(gè)方法:
Map集合最典型的用法就是成對(duì)地添加、刪除key-value對(duì)谷徙,然后就是判斷該Map中是否包含指定key,是否包含指定value驯绎,也可以通過(guò)Map提供的keySet()方法獲取所有key組成的集合完慧,然后使用foreach循環(huán)來(lái)遍歷Map的所有key,根據(jù)key即可遍歷所有的value剩失。下面程序代碼示范Map的一些基本功能:
public class MapTest {
public static void main(String[] args){
Day day1 = new Day(1, 2, 3);
Day day2 = new Day(2, 3, 4);
Map<String,Day> map = new HashMap<String,Day>();
//成對(duì)放入key-value對(duì)
map.put("第一個(gè)", day1);
map.put("第二個(gè)", day2);
//判斷是否包含指定的key
System.out.println(map.containsKey("第一個(gè)"));
//判斷是否包含指定的value
System.out.println(map.containsValue(day1));
//循環(huán)遍歷
//1.獲得Map中所有key組成的set集合
Set<String> keySet = map.keySet();
//2.使用foreach進(jìn)行遍歷
for (String key : keySet) {
//根據(jù)key獲得指定的value
System.out.println(map.get(key));
}
//根據(jù)key來(lái)移除key-value對(duì)
map.remove("第一個(gè)");
System.out.println(map);
}
}
輸出結(jié)果:
true
true
Day [hour=2, minute=3, second=4]
Day [hour=1, minute=2, second=3]
{第二個(gè)=Day [hour=2, minute=3, second=4]}