Java集合框架超詳細(xì)小結(jié)
一:Collection集合
呼~(yú),歷過(guò)好幾天的奮戰(zhàn)終于把集合框架肝完了,b站某馬老師講的是真的非常詳細(xì)而且動(dòng)聽(tīng),原理給你分析得明明白白的,此前也找了許多關(guān)于集合這一大章節(jié)的視頻,發(fā)現(xiàn)更多的是針對(duì)于使用,原理講的并不是很多,這就導(dǎo)致我在練習(xí)或者回顧時(shí)還是一知半解。以下是我結(jié)合視頻以及個(gè)人的一些理解和體會(huì)做的筆記總結(jié)。路漫漫其修遠(yuǎn)兮,吾將上下而求索,希望這篇總結(jié)對(duì)你有些許幫助,嘻嘻!
1.1集合概述:
集合:Java中提供的一種容器,可以用來(lái)存儲(chǔ)多個(gè)數(shù)據(jù)。java集合大致可以分為Set,List,Queue和Map四種體系。
數(shù)組和集合的區(qū)別:
- 數(shù)組的長(zhǎng)度是固定的。集合的長(zhǎng)度是可變的。
- 數(shù)組存儲(chǔ)的是同一類(lèi)型的數(shù)據(jù),可以存儲(chǔ)基本數(shù)據(jù)類(lèi)型值。容器能存儲(chǔ)對(duì)象,而且存儲(chǔ)對(duì)象的類(lèi)型可以不一致。在開(kāi)發(fā)中當(dāng)對(duì)象多的時(shí)候,使用容器進(jìn)行存儲(chǔ)。
1.2集合架構(gòu)

單列集合體系結(jié)構(gòu):

Collection接口是所有單列集合的父接口,因此在單列集合中定義的List和set通用的一些方法,這些方法可以操作所有的單列集合。方法如下:
1.3Collection集合常用方法
- public boolean add(E e); 向集合中添加元素
- public boolean remove(E e); 刪除集合中的某個(gè)元素
- public void clear(); 清空集合中所有的元素
- public boolean contains(); 判斷集合中是否含有xxx元素
- publicboolean isEmpty(); 判斷集合是否為空
- publicint size(); 計(jì)算集合的長(zhǎng)度
- public Object[] toArray(); 將集合轉(zhuǎn)成一個(gè)數(shù)組
【參考代碼】
package Collection;
import java.util.ArrayList;
import java.util.Collection;
/*
Collection集合常用方法
boolean add(E e); 向集合中添加元素
boolean remove(E e); 刪除集合中的某個(gè)元素
void clear(); 清空集合中所有的元素
boolean contains(); 判斷集合中是否含有xxx元素
boolean isEmpty(); 判斷集合是否為空
int size(); 計(jì)算集合的長(zhǎng)度
Object[] toArray(); 將集合轉(zhuǎn)成一個(gè)數(shù)組
*/
public class Test {
public static void main(String[] args) {
//創(chuàng)建集合對(duì)象 , 可以多態(tài)使用
Collection<String>col = new ArrayList<>();
// Collection<String>col = new HashSet<>(); 下面的功能照樣能實(shí)現(xiàn):共性方法
col.add("小明"); // 添加元素
col.add("小紅");
col.add("小藍(lán)");
col.add("小綠");
System.out.println(col); //[小明, 小紅, 小藍(lán), 小綠]
//boolean remove(E e); 刪除集合中的某個(gè)元素
// boolean ans = col.remove("小明");
// System.out.println(ans);//true
// System.out.println(col);//[小紅, 小藍(lán), 小綠]
//void clear(); 清空集合中所有的元素
// col.clear();
// System.out.println(col);//[]
//boolean contains(); 判斷集合中是否含有xxx元素
// boolean result = col.contains("小明");
// System.out.println(result);//true
//boolean isEmpty(); 判斷集合是否為空
// boolean result = col.isEmpty();
// System.out.println(result);// 不為空f(shuō)alse
//int size(); 計(jì)算集合的長(zhǎng)度
// int len = col.size();
// System.out.println(len);// 4
//Object[] toArray(); 將集合轉(zhuǎn)成一個(gè)數(shù)組
Object[] arr = col.toArray();
// 遍歷數(shù)組
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
}
}
二:迭代器Iterator
引入:由于集合有多種,每種集合存儲(chǔ)跟讀取的方式都不一樣,好比衣柜、水瓶、藥瓶,你存和取的方式肯定不一樣。如果每種集合都定義一種遍歷方式那將十分的繁瑣。
迭代器(Iterator):它不是一個(gè)容器而是接口,它是一種用于訪(fǎng)問(wèn)容器的方法,可用于迭代 List、Set和Map等容器。
迭代:即Collection集合的通用獲取方式。再獲取元素之前先要判斷集合中是否有元素,如果有就將這個(gè)元素去取出來(lái),繼續(xù)再判斷,直到集合所有元素被取出來(lái)為止。即:一個(gè)一個(gè)的往外拿。
作用:幫我們遍歷或者拿到容器里邊的數(shù)據(jù)。
2.1Iterator接口
迭代器常用操作:
- next() 下一個(gè)
- hasNext() 判斷是否存在下一個(gè)元素
- remove() 刪除元素
迭代器的使用步驟:
- 使用集合中的的方法iterator()獲取迭代器的實(shí)現(xiàn)類(lèi)對(duì)象,使用Iterator接口接收(多態(tài))
- 使用Tterator接口中的方法hashnext()判斷還有沒(méi)有下一個(gè)元素
- 使用Tterator接口中的方法next()取出集合的下一個(gè)元素
【參考代碼】
package Iterator;
import javax.swing.text.html.parser.Entity;
import java.util.*;
public class Test {
public static void main(String[] args) {
//創(chuàng)建一個(gè)集合對(duì)象
Collection<String>col = new ArrayList();
//添加元素
col.add("小明");
col.add("小紅");
col.add("小藍(lán)");
col.add("小綠");
/*
1.使用集合的方法iterator()獲取迭代器的實(shí)現(xiàn)類(lèi)對(duì)象,使用Iterator接口接收(多態(tài))
注意:
Iterator接口也是有泛型的,迭代器的泛型跟集合走,集合是什么泛型,迭代器就是什么泛型
*/
// 多態(tài) 接口 實(shí)現(xiàn)類(lèi)對(duì)象
Iterator<String>it = col.iterator();
// 2.使用 Iterator接口中的hashNext方法判斷是否還有下一個(gè)元素
while(it.hasNext());{
// 3.使用 Iterator接口中的next方法取出集合的下一個(gè)元素
String str = it.next();
System.out.println(str);
}
}
}
2.2Iterator的實(shí)現(xiàn)原理:

2.3增強(qiáng)for()
增強(qiáng)for循環(huán)(for each循環(huán))是JDk1.5之后的一個(gè)高循環(huán),專(zhuān)門(mén)用來(lái)遍歷數(shù)組和集合的,所有的數(shù)組跟單列集合都可以使用。它的內(nèi)部原理就是一個(gè)迭代器Iterator,所以在遍歷過(guò)程中,不能對(duì)集合元素進(jìn)行增刪操作。
語(yǔ)法:
for(類(lèi)型 變量 : 數(shù)組/集合){// 數(shù)組或者集合里的每一項(xiàng)賦值給這個(gè)變量
// 循環(huán)體
}
【參考代碼】
String[] student = {"小明","小紅","小藍(lán)"};
// // 傳統(tǒng)遍歷方式
// for (int i = 0; i < student.length; i++) {
// System.out.println(student[i]);
// }
// 增強(qiáng)for
for(String c : student){
System.out.println(c);
}
--------------------------------
List<Integer>list = new ArrayList<Integer>();
list.add(123);
list.add(234);
list.add(456);
for(Integer n : list){
System.out.println(n);
}
注:增強(qiáng)for必須有被遍歷的目標(biāo)。目標(biāo)只能是數(shù)組或者Collection,而它僅僅作為遍歷操作實(shí)現(xiàn)
2.4迭代器注意事項(xiàng)
- 迭代器是一次性對(duì)象。我們不能重置迭代器,它不能被重用。
- 要再次遍歷同一集合的元素,請(qǐng)通過(guò)調(diào)用集合的iterator()方法來(lái)創(chuàng)建一個(gè)新的Iterator。
三:泛型
3.1泛型概述
在前面學(xué)習(xí)集合時(shí),我們知道集合時(shí)可以存放任意對(duì)象的,只要把對(duì)象存儲(chǔ)集合后,它們都會(huì)被向上轉(zhuǎn)型提升為Object類(lèi)型。當(dāng)我們要取出這些對(duì)象時(shí)必須進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換,由Object類(lèi)型變?yōu)樵瓉?lái)的類(lèi)型。

3.2泛型的優(yōu)缺點(diǎn)
不使用泛型:
- 好處:集合默認(rèn)類(lèi)型是Object類(lèi),可以存儲(chǔ)任意類(lèi)型的數(shù)據(jù)
- 弊端:不安全,會(huì)引發(fā)異常,需要強(qiáng)轉(zhuǎn)。
public static void main(String[] args) {
List list = new ArrayList();
list.add("小明");
list.add("小紅");
for (int i = 0; i < list.size(); i++) {
String s= (String)list.get(i) // 強(qiáng)轉(zhuǎn)
System.out.println(s);
}
}
使用泛型:
- 好處:避免了類(lèi)型強(qiáng)制轉(zhuǎn)化的麻煩,存的什么類(lèi)型,取出來(lái)的也是什么類(lèi)型;代碼運(yùn)行之后才會(huì)拋出異常,寫(xiě)代碼時(shí)不會(huì)報(bào)錯(cuò)
- 弊端:泛型是什么類(lèi)型只能存儲(chǔ)什么類(lèi)型的數(shù)據(jù)。
public static void main(String[] args) {
List<String> list = new ArrayList();// 規(guī)范了數(shù)據(jù)類(lèi)型,只能放字符串!
list.add("小明");
list.add("小紅");
//stringList.add(123);// 除了字符串以外的類(lèi)型不能加,報(bào)錯(cuò)!
for (int i = 0; i < list.size(); i++) {
String s = list.get(i); // 不用再?gòu)?qiáng)轉(zhuǎn)了
System.out.println(s);
}
}
在上述的實(shí)例中,我們只能添加String類(lèi)型的數(shù)據(jù),否則編譯器會(huì)報(bào)錯(cuò)。
3.3泛型的定義與使用
泛型類(lèi)
定義格式:
修飾符 class 類(lèi)名<泛型變量>{
}
// 注:泛型變量建議使用E、T、K、V
例如:
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
參考示例:

注:在創(chuàng)建對(duì)象時(shí)確定泛型的類(lèi)型
泛型方法
定義格式:
修飾符 <泛型變量> 返回值的類(lèi)型 方法名稱(chēng)(形參列表){
//方法體
}
注:含有泛型的方法,在調(diào)用的時(shí)候確定泛型的數(shù)據(jù)類(lèi)型
傳遞什么類(lèi)型的參數(shù),泛型就是什么類(lèi)型
參考示例:

泛型接口
定義格式:
public interface 接口名<泛型類(lèi)型> {
}
使用方式1:定義接口的實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)接口,并且指定接口的泛型

使用方式2:接口使用什么泛型,實(shí)現(xiàn)類(lèi)就使用什么泛型,類(lèi)跟著接口走。
就相當(dāng)于定義了一個(gè)含有泛型的類(lèi),創(chuàng)建對(duì)象的時(shí)候確定泛型的類(lèi)型。
下圖接口同上圖接口

3.4泛型的通配符
當(dāng)使用泛型類(lèi)或接口時(shí),傳遞數(shù)據(jù)中,泛型類(lèi)型不確定,可以通過(guò)通配符表示<?>表示。但一旦使用泛型的通配符后,只能使用Object類(lèi)中的共性方法,集合中元素自身方法無(wú)法使用。
通配符的基本使用
泛型的通配符:不知道使用什么類(lèi)型來(lái)接收的時(shí)候,此時(shí)可以使用 ? ,?表示未知通配符
此時(shí)只能接收數(shù)據(jù),不能往集合中存儲(chǔ)數(shù)據(jù)。
【參考代碼】
package FanXing;
import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Iterator;
/*
泛型的通配符:
?:代表數(shù)據(jù)類(lèi)型
使用方式:
不能在創(chuàng)建對(duì)象時(shí)使用
只能作為方法的傳遞參數(shù)使用
*/
public class Generic {
public static void main(String[] args) {
ArrayList<Integer>list01 = new ArrayList<>();
list01.add(123);
list01.add(456);
ArrayList<String>list02 = new ArrayList<>();
list02.add("小明");
list02.add("小紅");
// ......還有很多其它類(lèi)型
printArray(list01);
printArray(list02);
/*
定義一個(gè)方法,能遍歷所有類(lèi)型的ArrayList集合
這時(shí)候我們不知道ArrayList集合使用的是什么類(lèi)型,可以使用泛型的通配符:?來(lái)代表數(shù)據(jù)類(lèi)型
注意:泛型沒(méi)有繼承的概念
*/
}
public static void printArray(ArrayList<?>list){
// 使用迭代器遍歷集合
Iterator<?> it = list.iterator();
while(it.hasNext()){
Object obj = it.next();//it.next()取出的元素是Object類(lèi)。Object類(lèi) 可以接收任意的數(shù)據(jù)類(lèi)型
System.out.println(obj);
}
}
}
通配符高級(jí)使用-----受限泛型
之前設(shè)置泛型的時(shí)候,實(shí)際上是可以可以任意設(shè)置的,只要是類(lèi)就可以設(shè)置。但在Java的泛型中可以指定一個(gè)泛型的上限和下限。
泛型的上限:
- 格式:類(lèi)型名稱(chēng)<? extends E >對(duì)象名稱(chēng) 代表的泛型只能是E類(lèi)型的子類(lèi)/本身
- 意義:只能接收該類(lèi)型及其子集
泛型的下限:
- 格式:類(lèi)型名稱(chēng)<? super E >對(duì)象名稱(chēng) 代表的泛型只能是E類(lèi)型的父類(lèi)/本身
- 意義:只能接收該類(lèi)型及其父類(lèi)
比如:Object類(lèi)、String類(lèi)、Number類(lèi)、Integer類(lèi),其中Number類(lèi)是Integer的父類(lèi)。
四:Java常見(jiàn)數(shù)據(jù)結(jié)構(gòu)
集合是基于數(shù)據(jù)結(jié)構(gòu)做出來(lái)的,不同的集合底層采用不同的數(shù)據(jù)結(jié)構(gòu)。不同的數(shù)據(jù)結(jié)構(gòu),功能和作用是不一樣的。
數(shù)據(jù)結(jié)構(gòu)是指數(shù)據(jù)以什么方式組織在一起。不同的數(shù)據(jù)結(jié)構(gòu),增刪查的性能是不一樣的。
4.1棧
棧:stack,又稱(chēng)堆棧,它是運(yùn)算受限的線(xiàn)性表,只能在棧的受限一端進(jìn)行插入和刪除操作。
特點(diǎn):先進(jìn)后出
4.2隊(duì)列
隊(duì)列:queue,簡(jiǎn)稱(chēng)隊(duì),它同棧由于也是運(yùn)算受限的線(xiàn)性表,只能在表的一端進(jìn)行插入操作,而在表的另一端進(jìn)行刪除操作。
特點(diǎn):先進(jìn)先出
4.3數(shù)組
數(shù)組:Array,是個(gè)有序的元素序列,數(shù)組在內(nèi)存中開(kāi)辟一段連續(xù)的空間。
特點(diǎn):
查詢(xún)快:隨機(jī)存取,通過(guò)索引可以快速訪(fǎng)問(wèn)元素
增刪慢:靜態(tài)分配內(nèi)存,數(shù)組的長(zhǎng)度是固定,存在空間閑置或者溢出現(xiàn)象;不適合進(jìn)行插入和刪除操作,需要移動(dòng)大量元素。
4.4鏈表
鏈表:linked list,由一系列結(jié)點(diǎn)node組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)產(chǎn)生。每個(gè)節(jié)點(diǎn)包含兩個(gè)部分:數(shù)據(jù)域(data)和指向下一個(gè)節(jié)點(diǎn)的指針域(next)。鏈表包括單鏈表和雙向鏈表。
單鏈表:鏈表中只有一條鏈子,不能保證元素的順序(存儲(chǔ)和取出的順序可能不一致)
雙向鏈表:鏈表中只有兩條鏈子,有一條鏈子專(zhuān)門(mén)記錄元素的順序,是一個(gè)有序的集合。
特點(diǎn):
查詢(xún)慢:鏈表的地址不是連續(xù)的,每次查詢(xún)都要從頭到尾進(jìn)行遍歷。
增刪快:動(dòng)態(tài)分派內(nèi)存,增/刪一個(gè)節(jié)點(diǎn)對(duì)于鏈表整體結(jié)構(gòu)沒(méi)有影響,增刪操作效率高。
4.5紅黑樹(shù)
紅黑樹(shù):R-B Tree,全稱(chēng)是Red-Black Tree,又稱(chēng)為“紅黑樹(shù)”,它一種特殊的二叉查找樹(shù)。紅黑樹(shù)的每個(gè)節(jié)點(diǎn)上都有存儲(chǔ)位表示節(jié)點(diǎn)的顏色,可以是紅(Red)或黑(Black),它是一種弱平衡二叉樹(shù)(Weak AVL)。
特點(diǎn):
(1)每個(gè)節(jié)點(diǎn)或者是黑色,或者是紅色。 (2)根節(jié)點(diǎn)是黑色。 (3)每個(gè)葉子節(jié)點(diǎn)(NIL)是黑色。 [注意:這里葉子節(jié)點(diǎn),是指為空(NIL或NULL)的葉子節(jié)點(diǎn)!] (4)如果一個(gè)節(jié)點(diǎn)是紅色的,則它的子節(jié)點(diǎn)必須是黑色的。 (5)從一個(gè)節(jié)點(diǎn)到該節(jié)點(diǎn)的子孫節(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑節(jié)點(diǎn)。
注:以上數(shù)據(jù)結(jié)構(gòu)可以結(jié)合所學(xué)過(guò)c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)
五:List集合體系
5.1List概述
List集合體系:添加元素,是有序,可重復(fù),有索引的,大小可變。實(shí)際開(kāi)發(fā)中常用的是ArrayList集合。List集合體系包括以下幾種:
- ArrayList——添加元素,是有序,可重復(fù),有索引的。
- LinkedList——添加元素,是有序,可重復(fù),有索引的。
- Vector——查詢(xún)快,增刪慢;運(yùn)行效率慢、線(xiàn)程安全
List集合繼承了Collection集合的全部功能,同時(shí)因?yàn)長(zhǎng)ist集合系列有索引,所以多了很多按照索引操作元素的方法:
add(int index, E element) 根據(jù)索引添加元素 get(int index) 根據(jù)索引獲取元素 remove(int index) 根據(jù)索引刪除元素 set(int index, E element) 根據(jù)索引修改該位置上的元素 contains(E element)判斷容器是否含有XXX東西 clear() 清空集合中的元素 size()計(jì)算集合的大小
【參考代碼】
package Collection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class TestList {
public static void main(String[] args) {
List<String>list = new ArrayList();
// 換成Linkedist 下面的操作都能一樣實(shí)現(xiàn)
list.add("小明");
list.add("小紅");
list.add("小藍(lán)");
list.add("小綠");
list.add("小明");
// // 在某個(gè)索引位置往集合中添加元素
// list.add(2,"哈哈哈哈");
// System.out.println(list);
// // 刪除集合中某個(gè)元素
// list.remove("小藍(lán)");
// // 根據(jù)索引獲取元素
// System.out.println(list.get(0));
// // 修改索引位置處的元素
// list.set(0,"小明很明白!");
// System.out.println(list.get(0));//小明很明白!
// // 計(jì)算列表的大小(長(zhǎng)度):
// System.out.println(list.size());
// //判斷列表中是否有xxx false
// System.out.println(list.contains("小藍(lán)"));
}
}
5.2List遍歷方式
for循環(huán)
// 遍歷列表
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
System.out.println(str);
}
迭代器
Iterator<String>it = list.iterator(); // 創(chuàng)建一個(gè)List的迭代器
while(it.hasNext()){// 判斷有沒(méi)有下一個(gè)元素
String s = it.next();
System.out.println(s);
}
增強(qiáng)for
List<String>list = new ArrayList<>();
for(String s : list){
System.out.println(s);
}
Lambda表達(dá)式(了解)
list.foreach(s -> {
System.out.println(s);
});
5.3ArrayList集合
ArrayList集合存儲(chǔ)的結(jié)構(gòu)是數(shù)組結(jié)構(gòu),元素增刪慢,查詢(xún)快。最常用。
5.4LinkedList集合
LinkedList集合存儲(chǔ)的結(jié)構(gòu)是鏈表結(jié)構(gòu),方便元素的添加、刪除操作。LinkedList是一個(gè)雙向鏈表
LinkedList的特點(diǎn):
底層是一個(gè)鏈表結(jié)構(gòu):查詢(xún)慢,增刪快
里邊含有大量操作首尾元素的方法
注:使用LinkedList集合特有的方法,不能使用多態(tài),命名要注意了!
實(shí)際開(kāi)發(fā)中對(duì)一個(gè)集合的添加、刪除操作經(jīng)常涉及首尾操作,LinkedList提供了很多操作首尾元素方法
public void addFirst(E e); 將指定的元素插到列表開(kāi)頭。 public void addLat(E e); 將指定的元素插到列表結(jié)尾。 此方法等效于add()方法 public void push(E e); 將元素推入此列表所示的堆棧。 此方法等效于addFirst()方法 public E getFirst(); 返回此列表的第一個(gè)元素 public E getLast(); 返回此列表的最后一個(gè)元素 public E removeFirst(); 移除并返回此列表的第一個(gè)元素 public E removeLast(); 移除并返回此列表的最后一個(gè)元素 public E pop(E e); 入此列表所示的堆棧中彈出一個(gè)元素。 public boolean isEmpty(); 如果列表為空 返回true
【參考代碼】
package Collection;
/*
public void addFirst(E e); 將指定的元素插到列表開(kāi)頭。
public void addLast(E e); 將指定的元素插到列表結(jié)尾。
public void push(E e); 將元素推入此列表所示的堆棧。
public E getFrist(); 返回此列表的第一個(gè)元素
public E getLast(); 返回此列表的最后一個(gè)元素
public E removeFrist(); 移除并返回此列表的第一個(gè)元素
public E removeLast(); 移除并返回此列表的最后一個(gè)元素
public E pop(E e); 入此列表所示的堆棧中彈出一個(gè)元素。
public boolean isEmpty(); 如果列表為空 返回true
*/
import java.util.LinkedList;
import java.util.List;
public class TestLinkedList {
public static void main(String[] args) {
show01();
show02();
show03();
}
/*
public void addFirst(E e); 將指定的元素插到列表開(kāi)頭。
public void addLast(E e); 將指定的元素插到列表結(jié)尾。
public void push(E e); 將元素推入此列表所示的堆棧
*/
public static void show01(){
// 注:LinkedList特有的方法不能使用多態(tài)!
// List<String> list = new LinkedList<>(); 是不對(duì)的
LinkedList<String>list = new LinkedList<>();
// add()添加元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);//[a, b, c]
list.addFirst("hhh");
//public void push(E e); 將元素推入此列表所示的堆棧。 等效于addFirst()
list.push("hhh");
System.out.println(list);
//public void lastFrist(E e); 將指定的元素插到列表結(jié)尾。 等效于add()
list.addLast("com");
System.out.println(list);
}
/*
public E getFrist(); 返回此列表的第一個(gè)元素
public E getLast(); 返回此列表的最后一個(gè)元素
*/
public static void show02(){
LinkedList<String>list = new LinkedList<>();
// add()添加元素
list.add("a");
list.add("b");
list.add("c");
// list.clear(); // 清空集合中所有元素
if(! list.isEmpty()){
System.out.println(list.getFirst());//a
System.out.println(list.getLast());//c
}
}
/*
public E removeFrist(); 移除并返回此列表的第一個(gè)元素
public E removeLast(); 移除并返回此列表的最后一個(gè)元素
public E pop(E e); 入此列表所示的堆棧中彈出一個(gè)元素。
*/
public static void show03(){
LinkedList<String>list = new LinkedList<>();
// add()添加元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list.pop());
//public E pop(E e); 入此列表所示的堆棧中彈出一個(gè)元素。 等效于 removefirst()
//System.out.println(list.pop());
System.out.println(list.removeFirst());//a
System.out.println(list.removeLast());//c
System.out.println(list);//[b]
}
}
注:使用LinkedList集合特有的方法,不能使用多態(tài)。
5.5Vector集合(了解)
數(shù)組結(jié)構(gòu)實(shí)現(xiàn),查詢(xún)快,增刪慢;
JDK1.0版本,運(yùn)行效率慢、線(xiàn)程安全
【參考代碼】
package Collection;
import javax.swing.text.html.HTMLDocument;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
/*
Vector集合的使用
存儲(chǔ)結(jié)構(gòu):數(shù)組
*/
public class VectorTest {
public static void main(String[] args) {
// 創(chuàng)建集合
Vector<String>vector = new Vector<>();
// 添加元素
vector.add("小明");
vector.add("小紅");
vector.add("小藍(lán)");
System.out.println("元素個(gè)數(shù)"+ vector.size());
// 判斷
System.out.println(vector.contains("小明"));
System.out.println(vector.isEmpty());
//刪除
vector.remove("小紅");
System.out.println(vector);
//清空 clear(); vector.clear();
// 遍歷
Iterator<String> it = vector.iterator();
while (it.hasNext()){
String str = it.next();
System.out.println(str);
}
//vector獨(dú)有的遍歷 使用枚舉器
// Enumeration<String>en = vector.elements();
// while (en.hasMoreElements()){
// String s = en.nextElement();
// System.out.println(s);
// }
}
}
六:Set系列集合
6.1概述
Set系列集合:添加的元素,是無(wú)序的,不重復(fù)的,無(wú)索引的(索引的操作不能用)。
——HashSet:添加的元素,是無(wú)序的,不重復(fù)的,無(wú)索引的。
——LinkedHashSet:添加的元素,是有序的,不重復(fù)的,無(wú)索引的。
——TreeSet:不重復(fù),無(wú)索引,按照大小默認(rèn)升序排序??!(可排序集合)
遍歷方式:由于Set集合五索引,故沒(méi)有for循環(huán)遍歷,只有三種遍歷。
6.2Set集合存儲(chǔ)元素不重復(fù)的原理

注:存儲(chǔ)的字符串,Integer等類(lèi)型的數(shù)據(jù),它們是Java已經(jīng)定義好了類(lèi),它們都重寫(xiě)了hashCode方法和equals方法,保證了元素的唯一性!
HashSet 保證元素唯一性的原理
我們使用 Set 集合都是需要去掉重復(fù)元素的, 如果在存儲(chǔ)的時(shí)候逐個(gè) equals() 比較, 效率較低,哈希算法提高了去重復(fù)的效率, 降低了使用 equals() 方法的次數(shù)。
當(dāng) HashSet 調(diào)用 add() 方法存儲(chǔ)對(duì)象的時(shí)候, 先調(diào)用對(duì)象的 hashCode() 方法得到一個(gè)哈希值, 然后在集合中查找是否有哈希值相同的對(duì)象,如果沒(méi)有哈希值相同的對(duì)象就直接存入集合。如果有哈希值相同的對(duì)象, 就和哈希值相同的對(duì)象逐個(gè)進(jìn)行 equals() 比較,比較結(jié)果為 false 就存入, true 則不存。存儲(chǔ)元素必需要重寫(xiě)HashCode方法和equals方法
6.3HashSet存儲(chǔ)自定義類(lèi)型元素
給HashSet中存放自定義的類(lèi)型時(shí),必需要重寫(xiě)HashCode方法和equals方法,建立自己的比較方式,才能保證HashSet集合中對(duì)象的唯一性!
【參考代碼】
Person類(lèi):
package Collection;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 用于打印
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// 重寫(xiě)hashCode方法和equals方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, 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;
}
}
// 主控制臺(tái)
package Collection;
import java.util.HashSet;
import java.util.Set;
/*
HashSet存儲(chǔ)自定義類(lèi)型的元素
Set集合保證元素唯一性:
存儲(chǔ)的元素(String Integer,...Student,Person...) 必須重寫(xiě)hashCode方法和equals方法
要求:
同名且同年齡視為同一個(gè)人噢
*/
public class TestHaxhSet {
public static void main(String[] args) {
// 創(chuàng)建hashSet集合存儲(chǔ)Person
Set<Person>set = new HashSet<>();
//集合類(lèi)存放對(duì)象的!
// 創(chuàng)建對(duì)象(人)
/*
// 在沒(méi)有重寫(xiě)hashCode方法和equals方法前,它們的哈希值都是不一樣的,equals也為false 故沒(méi)有重復(fù)
Person p1 = new Person("小明",18);
Person p2 = new Person("小明",19);
Person p3 = new Person("小明",18);
System.out.println(p1.hashCode());// 460141958
System.out.println(p2.hashCode());// 1163157884
System.out.println(p3.hashCode());// 1956725890
System.out.println(p1.equals(p2));// false
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);// [Person{name='小明', age=18}, Person{name='小明', age=19}, Person{name='小明', age=18}]
*/
// 重寫(xiě)hashCode方法和equals方法之后set對(duì)象就唯一性了
Person p1 = new Person("小明",18);
Person p2 = new Person("小明",19);
Person p3 = new Person("小明",18);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);// [Person{name='小明', age=19}, Person{name='小明', age=18}]
}
}
6.4LinkedHashSet集合
我們知道HashSet保證元素的唯一性,但存放進(jìn)去的元素是無(wú)序的,那我們要保證有序,該怎么辦好呢?
在HashSet下面的一個(gè)子類(lèi)Java.util.LinkedHashSet。它是鏈表和哈希表組合的一個(gè)數(shù)據(jù)結(jié)構(gòu)。
LinkedHashSet集合的特點(diǎn):
底層是一個(gè)哈希表(數(shù)組+鏈表/紅黑樹(shù))+鏈表:多了一條鏈表(記錄元素的存儲(chǔ)順序),保證元素有序
具有可預(yù)知迭代順序的 Set 接口的哈希表和鏈接列表實(shí)現(xiàn),即按照將元素插入到 set 中的順序(插入順序)進(jìn)行迭代。
HashSet與LinkedHashSet的區(qū)別:
【參考代碼】
package Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class TestHashSet {
public static void main(String[] args) {
Set<String>set = new HashSet<>();
set.add("kkk");
set.add("abc");
set.add("abc");
set.add("afterglow");
System.out.println(set);//[afterglow, abc, kkk] 無(wú)序,不重復(fù)
Set<String>Linkset = new LinkedHashSet<>();
Linkset.add("kkk");
Linkset.add("abc");
Linkset.add("abc");
Linkset.add("afterglow");
System.out.println(Linkset);//[kkk, abc, afterglow] 有序,不重復(fù)
}
}
6.5可變參數(shù)
使用前提:
如果我們定義一個(gè)方法需要接收多個(gè)參數(shù),并且多個(gè)參數(shù)類(lèi)型一致,我們可以對(duì)其做如下格式的簡(jiǎn)化:
修飾符 返回值類(lèi)型 方法名(參數(shù)類(lèi)型... 形參名){ }
這個(gè)寫(xiě)法完全等價(jià)于:
修飾符 返回值類(lèi)型 方法名(參數(shù)類(lèi)型[] 形參名){ } ,
后者在調(diào)用時(shí)必須傳遞數(shù)組,而前者可以直接傳遞數(shù)據(jù)類(lèi)型。
可變參數(shù)原理:
可變參數(shù)底層是一個(gè)數(shù)組,根據(jù)參數(shù)個(gè)數(shù)不同,會(huì)創(chuàng)建不同長(zhǎng)度的數(shù)組來(lái)存儲(chǔ)這些參數(shù)。傳遞參數(shù)的個(gè)數(shù),可以是0~n個(gè)
【參考代碼】
package Collection;
public class KeBiancanShu {
public static void main(String[] args) {
int i =add(1,2,3,4);
System.out.println(i);
}
// // 兩個(gè)數(shù)的和
// public static int add(int a, int b){
// return a + b;
// }
// // 三個(gè)數(shù)的和,要是多個(gè)一直往下寫(xiě),很麻煩!
// public static int add(int a, int b, int c){
// return a + b +c;
// }
/*
求0~n個(gè)整數(shù)的和
數(shù)據(jù)類(lèi)型已經(jīng)確定:int
參數(shù)個(gè)數(shù)不確定,可以使用可變參數(shù)
*/
public static int add(int...arr){
// System.out.println(arr);// [I@1b6d3586 底層是一個(gè)數(shù)組
// System.out.println(arr.length);// 可變數(shù)組的長(zhǎng)度,卻決于你添加的個(gè)數(shù)
int sum = 0;
for (int i : arr){
sum += i;
}
return sum;
}
}
注意事項(xiàng):
- 一個(gè)方法的參數(shù)列表,只能有一個(gè)可變參數(shù)
- 如果方法的參數(shù)有多個(gè),那么可變參數(shù)必須寫(xiě)在參數(shù)列表的末尾!
【示例代碼】
/*
可變參數(shù)注意事項(xiàng):
一個(gè)方法的參數(shù)列表,只能有一個(gè)可變參數(shù)
如果方法的參數(shù)有多個(gè),那么可變參數(shù)必須寫(xiě)在參數(shù)列表的末尾!
*/
//一個(gè)方法的參數(shù)列表,只能有一個(gè)可變參數(shù)
// public static void method01(int...a,String...b){ 報(bào)錯(cuò)!
// }
//如果方法的參數(shù)有多個(gè),那么可變參數(shù)必須寫(xiě)在參數(shù)列表的末尾!
public static void method02(String b, double c, int...a){
}
七:Collections工具類(lèi)
7.1常用方法:
- Java.utils.collections 是集合工具類(lèi),用于對(duì)集合進(jìn)行操作。常用功能如下:
max() / min():求集合的最大 / 小值public static <T> boolenan addAll(Collect<T> c , T. . . elements):往集合中添加一些元素public static void shuffle(List<?> list):打亂集合順序public static void sort(List<T> list):將集合按照默認(rèn)規(guī)則(升序)進(jìn)行排序public static void sort(List<T> list , Comparator<? super T >);將集合按照指定的規(guī)則進(jìn)行排序
【參考代碼】
public class Test {
public static void main(String[] args) {
List<Integer>list = new ArrayList<Integer>();
list.add(120);
list.add(20);
list.add(220);
// 求最值
Integer max = Collections.max(list);
System.out.println(max);
Integer min = Collections.min(list);
System.out.println(min);
// 排序
Collections.sort(list);
System.out.println(list);
// 打亂順序
Collections.shuffle(list); // 斗地主發(fā)牌
System.out.println(list);
// 不定參數(shù)添加
Collections.addAll(list,456,789);
System.out.println(list);//[220, 20, 120, 456, 789]
}
}
sort(List < T > list)使用
注意:
sort(List<T> list)使用前提:
排序的集合里邊存儲(chǔ)的元素,必須實(shí)現(xiàn)Comparable接口,重寫(xiě)接口中的方法compareTo定義排序的規(guī)則。在Java中Integer、String等等數(shù)據(jù)類(lèi)型已經(jīng)幫我們實(shí)現(xiàn)Comparable接口并重寫(xiě)接口中的方法compareTo了。如果要對(duì)自己定義的類(lèi)進(jìn)行排序,我們就要自己實(shí)現(xiàn)接口并重寫(xiě)compareTo然后進(jìn)行自定義排序規(guī)則。
Comparable接口的排序規(guī)則:
自己(this) - 參數(shù):升序,反之降序
【示例參考】:比較自定義類(lèi)型

輸出結(jié)果:
[Student{name='小明', age=18}, Student{name='小紅', age=20}, Student{name='小藍(lán)', age=19}] [Student{name='小明', age=18}, Student{name='小藍(lán)', age=19}, Student{name='小紅', age=20}]
- sort(List< T > list , Comparator<? super T >)
- sort(List< T > list , Comparator<? super T >)的使用:
- Comparator:相當(dāng)于找一個(gè)第三放的裁判,按照Comparator比較器里面重寫(xiě)的compare方法對(duì)元素進(jìn)行排序比較
Comparator的比較規(guī)則:
o1 - o2 升序
【參考代碼】
public class TestComparator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;// 升序
// return o2 - o1;// 降序
}
});
System.out.println(list);// [1, 2, 3]
}
}
【示例參考】:比較自定義類(lèi)型

Comparator和Comparable的區(qū)別
- Comparable:自己(this)和別人(參數(shù))比較,自己需要實(shí)現(xiàn)Comparable接口,重寫(xiě)比較規(guī)則compareTo方法
- Comparator:相當(dāng)于找一個(gè)第三放的裁判,按照Comparator比較器里面重寫(xiě)的compare方法對(duì)元素進(jìn)行排序比較
八:Map集合
8.1概述
Map集合的特點(diǎn)
- Map是一個(gè)雙列集合,其中每個(gè)元素表示一個(gè)鍵值對(duì)作為<key,value> ;
- Map集合中的元素,key和value的數(shù)據(jù)類(lèi)型可以相同,也可以不同
- Map集合中的元素,key不允許出現(xiàn)重復(fù),value可以重復(fù)
- Map集合中的元素,key和value是一一對(duì)應(yīng)的(映射)
注:映射由Map<K,V>接口的實(shí)例表示,它不是繼承自Collection接口。
8.2Map集合常見(jiàn)子類(lèi)
Map系列集合,常用子類(lèi)的包括:
——HashMap
——LinkedHashMap
【HashMap集合】
java.util.HashMap<k , v >集合implements Map<k , v>接口.
HashMap集合的特點(diǎn):
HashMap底層是哈希表:查詢(xún)速度特別快
JDK1.8之前:數(shù)組 + 單項(xiàng)鏈表
JDK1.8之后:數(shù)組 + 單項(xiàng)鏈表/紅黑樹(shù)(鏈表長(zhǎng)度超過(guò)8):提高查詢(xún)速
HashMap集合是一個(gè)無(wú)序的集合,存儲(chǔ)元素和取出元素的順序有可能不一致
【LinkedHashMap集合】
java.util.LinkedHashMap<k , v >集合extends HashMap<k , v>集合。
LinkedHashMap集合的特點(diǎn):
LinkedHashMap底層是哈希表 + 鏈表(保證迭代的順序)
HashMap集合是一個(gè)有序的集合,存儲(chǔ)元素和取出元素的順序是一致的
8.3Map接口中的常用方法
Map接口中定義了很多方法,常見(jiàn)如下:
public V put(K key , V value):把指定的鍵(key)和指定的值(value)添加到Map集合中public V remove(Object key):把指定的key所對(duì)應(yīng)的value從Map集合中刪除,返回被刪元素的值public V get(Object key):在集合中獲取指定key對(duì)應(yīng)value的元素boolean containsKey(Object key):判斷集合中是否含有xxxkeyboolean containsValue(Object key):判斷集合中是否含有xxxvaluepublic Set<K> KeySet():把Map中所有的key打包成(存儲(chǔ)到)set集合返回public Set< Map.Entry<K,V> > entrySet():獲取Map中所有key和value對(duì)象的集合(Entry)存儲(chǔ)在集合Set中
【參考代碼】
package Map;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
// 創(chuàng)建Map集合對(duì)象,多態(tài)
Map<Integer,String>map = new HashMap();
map.put(11,"小明");
map.put(22,"小紅");
map.put(33,"小藍(lán)");
map.put(44,"小綠");
System.out.println(map);// {33=小藍(lán), 22=小紅, 11=小明, 44=小綠} HashMap無(wú)序的
map.remove(44);// 刪除
System.out.println(map);// {33=小藍(lán), 22=小紅, 11=小明}
System.out.println(map.size()); //大小 3
System.out.println(map.containsKey(33)); //true
System.out.println(map.containsValue("小藍(lán)")); //true
map.put(22,"小芳"); // {33=小藍(lán), 22=小芳, 11=小明} 若出現(xiàn)重復(fù)的key原來(lái)的數(shù)據(jù)會(huì)被頂替
System.out.println(map);
// map.put(55,"小明");
// System.out.println(map);//是否被頂替卻決于key,key映射value,而不是value映射key {33=小藍(lán), 22=小芳, 55=小明, 11=小明}
System.out.println(map.keySet()); // [33, 22, 11] 把map中的key打包成Set集合的形式
System.out.println(map.get(33));// 小藍(lán) 通過(guò)key查詢(xún)value
}
}
8.4Map的遍歷
方法一:通過(guò)鍵找值的方式
- 使用Map集合中的方法keySet(),把Map集合里所有的key取出來(lái),存放到一個(gè)Set集合中
- 遍歷set集合,獲取Map集合中的每一個(gè)key
- 通過(guò)Map集合中的get(key)方法,找到value
【參考代碼】
package Map;
import javax.swing.text.html.HTMLDocument;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
// 創(chuàng)建Map集合對(duì)象
Map<String,Integer>map = new HashMap<>();
map.put("小明",18);
map.put("小紅",18);
map.put("小藍(lán)",19);
map.put("小綠",20);
//1. 使用Map集合中的方法keySet(),把Map集合里所有的key取出來(lái),存放到一個(gè)Set集合中\(zhòng)
Set<String> set = map.keySet();
//2.遍歷set集合,獲取Map集合中的每一個(gè)key
/* 使用while遍歷 */
Iterator <String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
//3.通過(guò)Map集合中的get(key)方法,找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-----------------------");
/* 使用增強(qiáng)for遍歷 */
for(String key : set){
//3.通過(guò)Map集合中的get(key)方法,找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}
}
【總結(jié)】:
while——迭代器遍歷:
Set<String> set = map.keySet();
Iterator <String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
Integer value = map.get(key);
System.out.println(key+"="+value);
}
增強(qiáng)for遍歷:
Set<String> set = map.keySet();
for(String key : set){
//3.通過(guò)Map集合中的get(key)方法,找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
方法二:鍵值對(duì)的方式遍歷(更加面向?qū)ο螅?/p>
把鍵值對(duì)當(dāng)成一個(gè)整體遍歷,增強(qiáng)for無(wú)法遍歷,這個(gè)整體不是類(lèi)型,因此Java提供了方法:
Map集合通過(guò)代碼Set<Map.Entry<K,V>> ,將鍵值對(duì)元素轉(zhuǎn)成了一個(gè)實(shí)體類(lèi)型,此時(shí)得到的是一個(gè)Entry對(duì)象,類(lèi)型是:Map.Entry<K,V>
- 通過(guò)Map集合中的entrySet()方法,把Map集合中的多個(gè)Entry對(duì)象取出來(lái),存儲(chǔ)到一個(gè)Set集合中
- 此時(shí)鍵值對(duì)元素的類(lèi)型就確定了,類(lèi)型是鍵值對(duì)實(shí)體類(lèi)型:Map.Entry<K,V>
- 接下來(lái)就可以用增強(qiáng)for遍歷了
【參考代碼】
package Map;
import javax.swing.text.html.HTMLDocument;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
// 創(chuàng)建Map集合對(duì)象
Map<String,Integer>map = new HashMap<>();
map.put("小明",18);
map.put("小紅",18);
map.put("小藍(lán)",19);
map.put("小綠",20);
//1.通過(guò)Map集合中的entrySet()方法,把Map集合中的多個(gè)Entry對(duì)象取出來(lái),存儲(chǔ)到一個(gè)Set集合中
Set<Map.Entry<String,Integer>> set = map.entrySet();
//遍歷set集合,獲取每一個(gè)Entry對(duì)象
//使用迭代器遍歷set集合
Iterator <Map.Entry<String,Integer>> it = set.iterator();
while (it.hasNext()){
Map.Entry<String,Integer>entry = it.next();
// 使用Entry對(duì)象中的getKey()和getValue()方法獲取鍵和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
System.out.println("-----------");
//增強(qiáng)for
for(Map.Entry<String,Integer> entry : set){
// 使用Entry對(duì)象中的getKey()和getValue()方法獲取鍵和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
【總結(jié)】:
while——迭代器遍歷:
Set<Map.Entry<String,Integer>> set = map.entrySet();
//遍歷set集合,獲取每一個(gè)Entry對(duì)象
//使用迭代器遍歷set集合
Iterator <Map.Entry<String,Integer>> it = set.iterator();
while (it.hasNext()){
Map.Entry<String,Integer>entry = it.next();
// 使用Entry對(duì)象中的getKey()和getValue()方法獲取鍵和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
增強(qiáng)for遍歷:
//增強(qiáng)for
for(Map.Entry<String,Integer> entry : set){
// 使用Entry對(duì)象中的getKey()和getValue()方法獲取鍵和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
Entry:表示一個(gè)key和value,它提供了獲取對(duì)應(yīng)key和value的方法:
public K getKey():獲取Entry中的key
public V getValue():獲取Entry中的value
方法二圖解:

8.5HashMap存儲(chǔ)自定義類(lèi)型鍵值
練習(xí):每位學(xué)生(姓名,年齡)都有自己的家庭住址。那么,既然有對(duì)應(yīng)關(guān)系,則將學(xué)生對(duì)象和家庭住址存儲(chǔ)到map集合中,學(xué)生作為鍵,地址為值。
注:學(xué)生姓名、年齡相同則視為同一人
package Map;
/*
hashMap存儲(chǔ)自定義類(lèi)型鍵值:
Map集合保證key是唯一的:
作為key元素,必須重寫(xiě)hashMap方法和equals方法,以保證key唯一
*/
import java.util.HashMap;
import java.util.Set;
public class HashMapSavePerson {
public static void main(String[] args) {
show01();
/*
上海-->HashMapSavePerson{name='小藍(lán)', age=18}
深圳-->HashMapSavePerson{name='小綠', age=18}
北京-->HashMapSavePerson{name='小紅', age=18}
key唯一
*/
}
/*
hashMap存儲(chǔ)自定義類(lèi)型鍵值:
key:String類(lèi)型
String類(lèi)重寫(xiě)hashCode方法和equals方法,可以保證key唯一
value:Person類(lèi)型
value可以重復(fù)(同名同年齡視為重復(fù))
*/
public static void show01(){
// 創(chuàng)造HashMap集合
HashMap<String,Person> map = new HashMap<>();
//往集合中添加元素
map.put("深圳",new Person("小明",18));
map.put("上海",new Person("小藍(lán)",18));
map.put("北京",new Person("小紅",18));
map.put("深圳",new Person("小綠",18));
// 使用keySet()增強(qiáng)for遍歷map集合
Set<String> set = map.keySet();
for(String key:set){
Person value = map.get(key);
System.out.println(key+"-->"+value);
// 因?yàn)樽址?lèi)(Java幫我們的)重寫(xiě)了hashCode方法和equals方法,所以鍵(key)是不能重復(fù)的
}
}
}
Person類(lèi):

下面這個(gè)是我們自己定義的key的類(lèi)型,Person類(lèi),上面例子的是String類(lèi):
package Map;
/*
hashMap存儲(chǔ)自定義類(lèi)型鍵值:
Map集合保證key是唯一的:
作為key元素,必須重寫(xiě)hashMap方法和equals方法,以保證key唯一
*/
import javax.swing.text.html.HTMLDocument;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapSavePerson {
public static void main(String[] args) {
show02();
}
/*
hashMap存儲(chǔ)自定義類(lèi)型鍵值:
key:Person類(lèi)型
Person就必須類(lèi)重寫(xiě)hashCode方法和equals方法,來(lái)保證key唯一
value:String類(lèi)型
value可以重復(fù)(同名同年齡視為重復(fù))
*/
public static void show02(){
// 創(chuàng)造HashMap集合
HashMap<Person,String> map02 = new HashMap<>();
// 往集合中添加元素
map02.put(new Person("張三",18),"法外狂徒");
map02.put(new Person("黃老板",18),"英國(guó)");
map02.put(new Person("陳奕迅",18),"中國(guó)");
map02.put(new Person("張三",18),"法外狂徒");
// 使用迭代器遍歷set集合中的Entry對(duì)象
Set<Map.Entry<Person,String>> set = map02.entrySet();
Iterator<Map.Entry<Person,String>> it = set.iterator();
while(it.hasNext()){
Map.Entry<Person,String> entry = it.next();
Person key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"--->"+value);
}
}
}

這里再介紹一下本例中Entry對(duì)象遍歷的圖解,再次加深印象:

8.6LinkedHashMap集合
我們知道HashMap保證key唯一,并且查詢(xún)速度快,可是成對(duì)元素存放進(jìn)去是沒(méi)有順序的(存和取的順序可能不一致),那我們要如何保證順序呢?
在HashMap下面有個(gè)LinkedHashMap(繼承關(guān)系),它是鏈表(記錄元素的順序)和哈希表組合的一個(gè)數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),是個(gè)有序的集合
【參考代碼】
package Map;
import javax.swing.text.html.HTMLDocument;
import java.util.*;
public class Test {
public static void main(String[] args) {
HashMap<String,String> map = new LinkedHashMap<>();
map.put("a","a");
map.put("c","c");
map.put("b","b");
map.put("d","d");
System.out.println(map);//{a=a, c=c, b=b, d=d}
}
}
輸出結(jié)果:(存儲(chǔ)和取出的順序是一樣的)
{a=a, c=c, b=b, d=d}
總結(jié)
看到這里,相信各位小伙伴們對(duì)Java集合這一章節(jié)的知識(shí)有了進(jìn)一步的理解,尤其是一些在之前學(xué)習(xí)時(shí)可能沒(méi)有注意到的知識(shí)或者原理,沒(méi)關(guān)系,這次都幫你總結(jié)在一起了。最后,感謝看到這里的你!愿你韶華不負(fù),青春無(wú)悔!
注: 由于自己剛剛開(kāi)始學(xué)習(xí)Java不久,語(yǔ)言文字描述、技術(shù)等各方面還不是很好,如果文章有任何錯(cuò)誤和建議,請(qǐng)各位大佬盡情評(píng)論留言!如果這篇文章對(duì)你有些許幫助,希望可愛(ài)親切的您點(diǎn)個(gè)贊推薦一手,非常感謝啦

到此這篇關(guān)于Java集合框架超詳細(xì)小結(jié)的文章就介紹到這了,更多相關(guān)Java集合框架內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
舉例講解Java的JSON類(lèi)庫(kù)GSON的基本用法
GSON是谷歌在GitHub上開(kāi)源的Java的JSON格式轉(zhuǎn)換類(lèi)庫(kù),能夠?qū)崿F(xiàn)Java對(duì)象向JSON的序列和反序列,這里我們就來(lái)舉例講解Java的JSON類(lèi)庫(kù)GSON的基本用法:2016-06-06
java四種引用及在LeakCanery中應(yīng)用詳解
這篇文章主要介紹了java四種引用及在LeakCanery中應(yīng)用,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09
SVN出現(xiàn)提示org.apache.subversion.javahl.ClientException: Attempt
這篇文章主要介紹了SVN出現(xiàn)提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir解決方案的相關(guān)資料,需要的朋友可以參考下2016-12-12
Spring Cloud與分布式系統(tǒng)簡(jiǎn)析
這篇文章主要介紹了Spring Cloud與分布式系統(tǒng)的相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-09-09
java使用selenium自動(dòng)化WebDriver等待的示例代碼
顯式等待和隱式等待是WebDriver中兩種常用的等待方式,它們都可以用來(lái)等待特定的條件滿(mǎn)足后再繼續(xù)執(zhí)行代碼,本文給大家介紹java使用selenium自動(dòng)化WebDriver等待,感興趣的朋友一起看看吧2023-09-09
Java BigDecimal解決double精度丟失的問(wèn)題
我們?cè)谌粘i_(kāi)發(fā)中, 有很多時(shí)候會(huì)遇到小數(shù)(double類(lèi)型)精確計(jì)算,本文主要介紹了Java BigDecimal解決double精度丟失的問(wèn)題,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11

