第6章 集合與泛型_第1頁
第6章 集合與泛型_第2頁
第6章 集合與泛型_第3頁
第6章 集合與泛型_第4頁
第6章 集合與泛型_第5頁
已閱讀5頁,還剩136頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第6章集合與泛型《Java基礎(chǔ)案例教程》(第3版)學(xué)習(xí)目標(biāo)/Target熟悉集合,能夠簡述集合的特點(diǎn)和Java集合框架的繼承體系熟悉List集合的作用,能夠簡述List集合常用的方法以及常用實(shí)現(xiàn)類的特點(diǎn)Collection集合的作用,能夠簡述Collection集合的常用方法熟悉Set集合的作用,能夠簡述Set集合常用實(shí)現(xiàn)類的特點(diǎn)學(xué)習(xí)目標(biāo)/Target掌握集合的遍歷,能夠使用Iterator迭代器和增強(qiáng)for循環(huán)遍歷集合掌握泛型的使用方法,能夠使用泛型指定集合中元素的類型掌握ArrayList集合和LinkedList集合的使用方法,能夠使用ArrayList集合和LinkedList集合的方法實(shí)現(xiàn)數(shù)據(jù)的增刪改查掌握Map集合的作用,能夠簡述Map集合常用的方法以及常用實(shí)現(xiàn)類的特點(diǎn)學(xué)習(xí)目標(biāo)/Target掌握HashMap集合和TreeMap集合的使用,能夠使用HashMap集合和TreeMap集合的方法實(shí)現(xiàn)數(shù)據(jù)的增刪改查熟悉Stream流的使用,能夠使用Stream流對集合進(jìn)行各種操作掌握HashSet集合和TreeSet集合的使用,能夠使用HashSet集合和TreeSet集合的方法實(shí)現(xiàn)數(shù)據(jù)的增刪改查章節(jié)概述/

Summary在Java程序中可以通過數(shù)組來保存數(shù)據(jù),但有時(shí)無法確定需要保存數(shù)據(jù)的數(shù)量,因?yàn)閿?shù)組的長度不可變,此時(shí)再使用數(shù)組存儲(chǔ)數(shù)據(jù)則不太合適。這種情況可以使用集合,Java中的集合就像一個(gè)可以存儲(chǔ)任意類型的對象并且長度可變的容器。Java中提供了多種具有不同特性的集合類,為了讓集合在使用時(shí)更加安全,還提供了泛型。本章將對Java中的集合和泛型進(jìn)行講解。目錄/Contents0102集合概述Collection集合0304List集合集合的遍歷目錄/Contents0506泛型Set集合0708Map集合Stream流集合概述6.16.1集合概述熟悉集合概述,能夠簡述集合的特點(diǎn)和Java集合框架的繼承體系

先定一個(gè)小目標(biāo)!6.1集合概述Java中的集合是指Java提供的一系列接口和實(shí)現(xiàn)類,通過這些接口和實(shí)現(xiàn)類可以很方便地存儲(chǔ)和管理對象,Java中的集合位于java.util包中,其按照存儲(chǔ)結(jié)構(gòu)可以分為單列集合Collection和雙列集合Map兩大類,單列集合中每個(gè)元素是一個(gè)獨(dú)立的單一數(shù)據(jù),而雙列集合中每個(gè)元素由兩個(gè)數(shù)據(jù)組成。6.1集合概述Collection集合單列集合類的根接口,它有兩個(gè)重要的子接口,分別為List和Set。其中,List中存放的元素有序且可重復(fù),常用的實(shí)現(xiàn)類有ArrayList和LinkedList;Set存放的元素?zé)o序且不允許有重復(fù)元素,常用的實(shí)現(xiàn)類有HashSet和TreeSet。Map集合雙列集合類的根接口,用于存儲(chǔ)具有鍵(Key)和值(Value)映射關(guān)系的鍵值對。其中,鍵是用于唯一標(biāo)識一個(gè)元素的對象,值是與該鍵相關(guān)聯(lián)的對象,在使用Map集合時(shí)可以通過指定的鍵找到對應(yīng)的值。Map集合的主要實(shí)現(xiàn)類有HashMap和TreeMap。6.1集合概述集合類的繼承體系。虛線框是接口,實(shí)線框是實(shí)現(xiàn)類。Vector類和HashTable類是線程安全類,但不考慮多線程時(shí),效率相對低一些,非多線程程序中建議使用ArrayList代替Vector,HashMap代替HashTable。Collection集合6.26.2Collection集合熟悉Collection集合的作用,能夠簡述Collection集合的常用方法

先定一個(gè)小目標(biāo)!6.2Collection集合Collection集合是所有單列集合的根接口,Collection集合常用的方法。方法聲明功能描述booleanadd(Ee)向集合中添加一個(gè)元素,E是所添加元素的數(shù)據(jù)類型booleanaddAll(Collectionc)將指定集合c中的所有元素添加到當(dāng)前集合中voidclear()刪除集合中的所有元素booleanremove(Objecto)刪除集合中的指定元素o,當(dāng)集合中包含了多個(gè)元素o時(shí),只刪除第1個(gè)符合條件的元素booleanremoveAll(Collectionc)刪除當(dāng)前集合中在集合c中存在的所有元素booleanisEmpty()判斷集合是否為空booleancontains(Objecto)判斷集合中是否存在指定元素obooleancontainsAll(Collectionc)判斷集合中是否存在指定集合c中的所有元素Iteratoriterator()返回集合的迭代器(Iterator),迭代器用于遍歷當(dāng)前集合的所有元素intsize()獲取集合中元素的個(gè)數(shù)List集合6.36.3List集合List集合是繼承自Collection集合的一個(gè)接口,是單列集合的一個(gè)重要分支,下面對List集合的相關(guān)知識進(jìn)行講解。6.3.1List集合簡介熟悉List集合的作用,能夠簡述List集合常用的方法以及常用實(shí)現(xiàn)類的特點(diǎn)

先定一個(gè)小目標(biāo)!6.3.1List集合簡介List集合是一個(gè)有序集合,允許存儲(chǔ)重復(fù)的元素。List集合中的元素按照插入的順序進(jìn)行存儲(chǔ),并且可以通過索引訪問和操作其中的元素。6.3.1List集合簡介List集合不但繼承了Collection集合中的全部方法,還提供了一些根據(jù)元素索引操作集合的特有方法。方法聲明功能描述voidadd(intindex,Objectelement)將對象element插入List集合的index索引處booleanaddAll(intindex,Collectionc)將集合c中的所有元素插入到List集合的index索引處Objectget(intindex)返回集合中索引位置為index的元素Objectremove(int

index)刪除集合中索引位置為index的元素Objectset(int

index,Object

element)將索引位置為index的元素替換成element對象,并將替換后的對象返回intindexOf(Object

o)返回對象o在List集合中第一次出現(xiàn)的索引位置intlastIndexOf(Object

o)返回對象o在List集合中最后一次出現(xiàn)的索引位置ListsubList(int

fromIndex,int

toIndex)返回從索引fromIndex(包括)到

toIndex(不包括)的所有元素組成的子集合6.3.2ArrayList集合掌握ArrayList集合的使用,能夠使用ArrayList實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.3.2ArrayList集合ArrayList集合是List集合的一個(gè)實(shí)現(xiàn)類,其內(nèi)部封裝了一個(gè)長度可變的數(shù)組對象,當(dāng)存入的元素超過數(shù)組長度時(shí),ArrayList會(huì)分配一個(gè)更大的數(shù)組來存儲(chǔ)這些元素,因此可以將ArrayList集合看作一個(gè)長度可變的數(shù)組。ArrayList具有數(shù)組的特點(diǎn),即讀取元素效率較高,插入和刪除元素時(shí),可能需要移動(dòng)其他元素的位置,導(dǎo)致效率相對低一些。6.3.2ArrayList集合ArrayList集合的構(gòu)造方法。方法聲明功能描述ArrayList()創(chuàng)建一個(gè)初始容量為10的空ArrayList對象ArrayList(intinitialCapacity)創(chuàng)建一個(gè)指定初始容量的空ArrayList對象ArrayList(Collection<?extendsE>c)創(chuàng)建一個(gè)包含指定Collection元素的ArrayList對象6.3.2ArrayList集合ArrayList集合提供了三種構(gòu)造方法。方法聲明功能描述ArrayList()創(chuàng)建一個(gè)初始容量為10的空ArrayList集合ArrayList(intinitialCapacity)創(chuàng)建一個(gè)指定初始容量的空ArrayList集合ArrayList(Collection<?extendsE>c)創(chuàng)建一個(gè)包含指定Collection元素的ArrayList集合6.3.2ArrayList集合通過一個(gè)案例演示ArrayList集合的基本操作。案例演示Example01.java源代碼6.3.2ArrayList集合案例的運(yùn)行結(jié)果如下圖所示。案例演示6.3.3LinkedList集合掌握LinkedList集合的使用,能夠使用LinkedList實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.3.3LinkedList集合ArrayList集合在查詢元素時(shí)速度很快,但在增刪元素時(shí)效率相對低一些。如果需要頻繁向集合中插入和刪除元素,可以使用List集合的另一個(gè)實(shí)現(xiàn)類LinkedList。6.3.3LinkedList集合LinkedList底層結(jié)構(gòu):雙向循環(huán)鏈表。鏈表中每個(gè)節(jié)點(diǎn)都通過引用的方式記錄它前一個(gè)或后一個(gè)節(jié)點(diǎn),從而將所有節(jié)點(diǎn)連接在一起。LinkedList集合插入和刪除元素的過程如下圖所示。6.3.3LinkedList集合LinkedList集合除了包含從List集合繼承過來的方法,還定義了一些自身特有的方法。方法聲明功能描述voidaddFirst(Object

o)將指定元素o插入集合的開頭voidaddLast(Object

o)將指定元素o添加到集合的結(jié)尾Object

getFirst()返回集合的第一個(gè)元素Object

getLast()返回集合的最后一個(gè)元素Object

removeFirst()移出并返回集合的第一個(gè)元素Object

removeLast()移出并返回集合的最后一個(gè)元素6.3.3LinkedList集合下面通過一個(gè)案例演示LinkedList常用方法的使用。案例演示Example02.java源代碼6.3.3LinkedList集合案例的運(yùn)行結(jié)果如下圖所示。案例演示集合的遍歷6.46.4集合的遍歷掌握集合的遍歷,能夠使用Iterator迭代器和增強(qiáng)for循環(huán)遍歷集合

先定一個(gè)小目標(biāo)!6.4集合的遍歷在開發(fā)中,對集合進(jìn)行遍歷是非常常見的操作。Java提供了一個(gè)接口Iterator,用于遍歷Collection集合中的元素。同時(shí),Java還提供了增強(qiáng)for循環(huán),也稱為for-each循環(huán),增強(qiáng)for循環(huán)在遍歷數(shù)組或者實(shí)現(xiàn)了Iterable接口的集合對象時(shí)非常方便,它會(huì)自動(dòng)迭代集合中的每個(gè)元素,無須手動(dòng)管理索引值。6.4集合的遍歷1.使用Iterator迭代器遍歷集合使用Iterator迭代器訪問集合中的元素的常用方法。方法聲明功能描述booleanhasNext()判斷集合中是否還有下一個(gè)元素可以訪問Objectnext()返回集合中的下一個(gè)元素,并將迭代指針移到下一個(gè)位置voidremove()從集合中移除通過next()方法獲取到的元素6.4集合的遍歷1.使用Iterator迭代器遍歷集合下面通過一個(gè)案例演示如何使用Iterator接口的方法對集合進(jìn)行遍歷。Example03.java源代碼6.4集合的遍歷1.使用Iterator迭代器遍歷集合案例的運(yùn)行結(jié)果如下圖所示。6.4集合的遍歷1.使用Iterator迭代器遍歷集合Iterator迭代器迭代元素的過程。6.4集合的遍歷腳下留心:并發(fā)修改異常在使用Iterator遍歷集合時(shí),如果在遍歷過程中使用集合對象的remove()方法刪除元素,會(huì)出現(xiàn)并發(fā)修改異常。這是Iterator用于檢測并發(fā)修改的一種機(jī)制,當(dāng)集合在遍歷過程中發(fā)生結(jié)構(gòu)性修改(例如添加元素,刪除元素),迭代器的內(nèi)部計(jì)數(shù)器發(fā)生變化,從而拋出并發(fā)修改異常(ConcurrentModificationException)。6.4集合的遍歷腳下留心:并發(fā)修改異常下面通過一個(gè)案例演示并發(fā)修改異常。Example04.java源代碼6.4集合的遍歷腳下留心:并發(fā)修改異常案例的運(yùn)行結(jié)果如下圖所示。6.4集合的遍歷腳下留心:并發(fā)修改異常如果想要安全地刪除集合中的元素,可以使用Iterator接口提供的remove()方法,它會(huì)在刪除元素后通知迭代器集合結(jié)構(gòu)發(fā)生了改變,避免出現(xiàn)并發(fā)修改異常。下面把Example04.java文件中第13~15行代碼修改為如下代碼。int[]arr; //聲明一個(gè)int[]類型的變量arr=newint[3]; //為arr分配3個(gè)數(shù)組元素的空間修改后再次運(yùn)行案例,結(jié)果如右圖所示。6.4集合的遍歷2.使用增強(qiáng)for循環(huán)遍歷集合從JDK5開始,Java提供了增強(qiáng)for循環(huán),簡化了Iterator接口遍歷的書寫。在遍歷集合時(shí),增強(qiáng)for循環(huán)語法上是在編譯時(shí)被轉(zhuǎn)換成Iterator迭代器的while循環(huán)實(shí)現(xiàn)的,因此它適用于實(shí)現(xiàn)了Iterator接口的集合類。6.4集合的遍歷2.使用增強(qiáng)for循環(huán)遍歷集合下面通過一個(gè)案例演示使用增強(qiáng)for循環(huán)遍歷集合的方式。Example05.java源代碼6.4集合的遍歷2.使用增強(qiáng)for循環(huán)遍歷集合案例的運(yùn)行效果如下圖所示。泛型6.56.5泛型掌握泛型的使用,能夠使用泛型指定集合中元素的類型

先定一個(gè)小目標(biāo)!6.5泛型默認(rèn)情況下把一個(gè)對象存入集合后,再次取出該對象時(shí),該對象的編譯類型就變成了Object類型。集合設(shè)計(jì)成這樣,提高了通用性,但是也帶來了一些類型不安全的問題。例如,集合可以存儲(chǔ)任意類型的對象,所以在取出對象時(shí)通常需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。如果不知道實(shí)際參數(shù)類型,就無法進(jìn)行強(qiáng)制類型轉(zhuǎn)換。6.5泛型案例演示下面通過一個(gè)案例演示集合存儲(chǔ)數(shù)據(jù)后,可能導(dǎo)致的類型不安全問題。Example06.java源代碼6.5泛型案例演示案例的運(yùn)行結(jié)果如下圖所示。6.5泛型為了避免進(jìn)行強(qiáng)制類型轉(zhuǎn)換,同時(shí)提高類型的安全性,Java引入了“參數(shù)化類型(parameterizedtype)”的概念,也就是泛型。泛型就是指給類型指定一個(gè)參數(shù),在使用時(shí)再指定此參數(shù)的具體值,這樣一來就可以根據(jù)不同的需求操作不同類型的數(shù)據(jù),使得代碼更加靈活和可擴(kuò)展。集合引入泛型之后,會(huì)在使用或者調(diào)用時(shí)傳入具體的類型以確定最終的數(shù)據(jù)類型,所以集合需要存儲(chǔ)什么類型的數(shù)據(jù),在創(chuàng)建集合時(shí)傳入對應(yīng)的類型即可。6.5泛型定義泛型時(shí),類型參數(shù)由一對尖括號(<>)包含在中間。下面使用泛型優(yōu)化文件Example06.java,將第5行代碼修改為如下代碼。List<Integer>list=newArrayList<>();上述代碼指定了List集合中元素的類型為Integer,這樣編譯器在編譯期就會(huì)做類型檢查,從而限制List集合中只能存儲(chǔ)Integer類型的元素。如果在集合中添加其他類型的元素,編譯器會(huì)提示錯(cuò)誤。如下圖所示。6.5泛型案例演示下面修改文件Example06.java,將List集合中原來的String類型的元素改為Integer類型,并在遍歷List集合時(shí)將元素的類型由Object改為Integer。修改后的Example06.java源代碼6.5泛型案例演示修改后的案例運(yùn)行結(jié)果如下圖所示。6.5泛型除了集合類等一些Java提供的類增加了泛型支持外,還可以根據(jù)需要自定義泛型類。例如,當(dāng)一個(gè)類的行為和功能需要適用于多個(gè)不同類型的數(shù)據(jù)時(shí),可以將這個(gè)類定義為泛型類。定義泛型類的語法格式如下:多學(xué)一招:自定義泛型類[修飾符]class類名<類型形參1,類型形參2,…,類型形參n>{//類的成員變量和成員方法}對上述語法格式的解釋:(1)類名<類型形參>:是一個(gè)整體的數(shù)據(jù)類型,通常稱為泛型類型。6.5泛型多學(xué)一招:自定義泛型類(2)類型形參沒有特定的意義,可以用任意一個(gè)大寫字母表示,但是為了提高可讀性,一般會(huì)使用有意義的字母表示。E:Element(元素),常在JavaCollection里使用,如List<E>,Iterator<E>,Set<E>。

K,V:Key,Value(Map的鍵值對)。N:Number(數(shù)字)。T:Type(類型),如String,Integer等。在泛型類中,類型形參可以用于指定成員變量的類型,成員方法的形參類型,以及成員方法的返回值類型。6.5泛型多學(xué)一招:自定義泛型類除了可以在類中使用泛型,還可以在接口和方法中使用泛型。聲明泛型接口的語法格式與泛型類的類似,具體如下:聲明泛型方法的格式如下:[修飾符]interface接口名<類型形參1,類型形參2,…,類型形參n>{}[修飾符]<類型形參1,類型形參2,…>返回值類型方法名稱(類型形參1形參變量1,類型形參2形參變量2,…){}6.5泛型多學(xué)一招:自定義泛型類在泛型類、泛型接口和泛型方法中,泛型類型一旦確定就不能更改。然而,在有些情況下需要指定可以操作的類型為某個(gè)類的父類或子類,這時(shí)候可以使用限定通配符來限制可操作類型的范圍。Java中的限定通配符分為兩種,具體如下所示。<?extendsT>,上界通配符。表示限定傳入的類型必須為T類型或T類的子類型。<?superT>,下界通配符。表示限定傳入的類型必須為T類型或T類的父類型。使用限定通配符后,泛型類型必須用限定內(nèi)的類型來進(jìn)行初始化,否則會(huì)編譯錯(cuò)誤。此外,Java中還提供了<?>表示非限定通配符,可以匹配任意類型,用于在泛型類、泛型接口和泛型方法中指定不確定的類型?!景咐?-1】社團(tuán)成員管理案例描述某校創(chuàng)立了一個(gè)書法社團(tuán),目前正在面向全校學(xué)生招募社團(tuán)成員。本案例要求為該社團(tuán)做一個(gè)社團(tuán)成員的管理系統(tǒng),實(shí)現(xiàn)對社團(tuán)成員的添加、移除、修改和查詢功能。社團(tuán)成員管理的具體要求如下。系統(tǒng)首頁:用于顯示社團(tuán)成員管理系統(tǒng)的所有功能,并根據(jù)用戶的選擇進(jìn)行對應(yīng)的操作。添加功能:添加成員時(shí)需要輸入成員的編號、姓名、年齡和年級。每個(gè)成員的成員編號唯一,若添加的編號已被占用,則提示用戶重新輸入。【案例6-1】社團(tuán)成員管理案例描述修改功能:修改功能只支持修改成員的年齡和年級兩個(gè)信息。修改成員信息時(shí)需要輸入成員的編號,若成員編號存在,則提示輸入修改后的年齡和年級;否則提示成員編號不存在的相關(guān)提示。查詢功能:查詢功能支持查詢所有成員和按年級查詢某個(gè)年級的所有成員。按年級查詢成員信息時(shí)需要輸入指定的年級,若社團(tuán)中存在該年級的成員,則顯示查詢到的成員信息;否則,提示社團(tuán)中沒有該年級的成員。移除功能:移除成員時(shí)需要輸入成員的編號,若成員編號存在,則進(jìn)行刪除并提示刪除成功;否則提示成員編號不存在的相關(guān)警告?!景咐?-1】社團(tuán)成員管理案例效果【案例6-1】社團(tuán)成員管理案例效果Set集合6.66.6Set集合Set集合是繼承自Collection集合的一個(gè)接口,與List集合不同的是,Set集合中存儲(chǔ)的元素?zé)o序且不允許重復(fù),并且沒有索引,因此無法使用普通for循環(huán)進(jìn)行遍歷。Set集合中的方法與Collection集合基本一致,常用的實(shí)現(xiàn)類有HashSet和TreeSet,下面將對這兩個(gè)集合進(jìn)行講解。6.6.1HashSet集合掌握HashSet集合的使用,能夠使用HashSet實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.6.1HashSet集合案例演示HashSet集合作為Set集合的一個(gè)實(shí)現(xiàn)類,它所存儲(chǔ)的元素是無序且不可重復(fù)的。下面先通過一個(gè)案例演示HashSet集合在使用上的特點(diǎn)。Example07.java源代碼6.6.1HashSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.6.1HashSet集合HashSet集合為什么能確保元素不重復(fù)呢6.6.1HashSet集合HashSet集合之所以能確保不出現(xiàn)重復(fù)的元素,是因?yàn)樗谔砑釉貢r(shí)做了很多工作。當(dāng)調(diào)用HashSet集合的add()方法添加元素時(shí),首先會(huì)調(diào)用當(dāng)前存入對象的hashCode()方法查找哈希值,然后根據(jù)哈希值計(jì)算該元素在集合中的位置,如果該位置上沒有元素,則直接添加元素。如果該位置上有元素存在,則會(huì)調(diào)用equals()方法讓當(dāng)前存入的元素和該位置上的元素比較,如果返回的結(jié)果為false,就將該元素添加到集合,如果返回的結(jié)果為true,則說明有重復(fù)元素,則將該元素舍棄。6.6.1HashSet集合HashSet集合存儲(chǔ)元素的流程。6.6.1HashSet集合案例演示下面通過一個(gè)案例演示將自定義學(xué)生類Student作為HashSet的元素存入集合。Example08.java源代碼6.6.1HashSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.6.1HashSet集合需要注意的是,Example08.java的運(yùn)行結(jié)果輸出了相同信息的對象,是因?yàn)樵诙xStudent類時(shí)沒有重寫hashCode()和equals()方法,對象的比較會(huì)使用對象的內(nèi)存地址進(jìn)行判斷,即兩個(gè)對象只有在內(nèi)存中的地址完全相同才會(huì)被認(rèn)為是相同對象。6.6.1HashSet集合下面將學(xué)號看作學(xué)生的唯一標(biāo)識,修改文件Example08.java,在Student類中添加重寫的hashCode()方法和equals()方法,具體代碼如下所示。publicinthashCode(){returnstuId.hashCode();//獲取stuId的哈希值}publicbooleanequals(Objectobj){if(this==obj){returntrue;}if(obj==null||!(objinstanceofStudent)){returnfalse;}Studentstudent=(Student)obj;returnthis.stuId.equals(student.stuId);}6.6.1HashSet集合修改后再次運(yùn)行文件Example08.java,運(yùn)行結(jié)果如下圖所示。6.6.1HashSet集合HashSet類有一個(gè)子類LinkedHashSet,它的底層也是哈希表的結(jié)構(gòu),但是還額外增加了雙向鏈表來維護(hù)內(nèi)部元素的存取順序,因此LinkedHashSet內(nèi)部元素的存取順序相同。6.6.1HashSet集合案例演示下面修改文件Example08.java,演示LinkedHashSet的使用。Example09.java源代碼6.6.1HashSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.6.2TreeSet集合掌握TreeSet集合的使用,能夠使用TreeSet實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.6.2TreeSet集合TreeSet集合是Set集合的一個(gè)實(shí)現(xiàn)類,它是一種基于平衡二叉樹實(shí)現(xiàn)的有序集合。所謂二叉樹就是由節(jié)點(diǎn)組成的樹形數(shù)據(jù)結(jié)構(gòu),每個(gè)節(jié)點(diǎn)最多有兩個(gè)子節(jié)點(diǎn),分別為左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)及其子節(jié)點(diǎn)組成的樹被稱為子樹,通常左側(cè)節(jié)點(diǎn)組成的樹稱為左子樹,右側(cè)節(jié)點(diǎn)組成的樹被稱為右子樹。其中,左子樹上的元素小于它的根節(jié)點(diǎn),而右子樹上的元素大于它的根節(jié)點(diǎn)。6.6.2TreeSet集合TreeSet集合是Set集合的一個(gè)實(shí)現(xiàn)類,它是一種基于平衡二叉樹實(shí)現(xiàn)的有序集合。所謂二叉樹就是由節(jié)點(diǎn)組成的樹形數(shù)據(jù)結(jié)構(gòu),每個(gè)節(jié)點(diǎn)最多有兩個(gè)子節(jié)點(diǎn),分別為左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)及其子節(jié)點(diǎn)組成的樹被稱為子樹,通常左側(cè)節(jié)點(diǎn)組成的樹稱為左子樹,右側(cè)節(jié)點(diǎn)組成的樹被稱為右子樹。其中,左子樹上的元素小于它的根節(jié)點(diǎn),而右子樹上的元素大于它的根節(jié)點(diǎn)。平衡二叉樹則是在二叉樹的基礎(chǔ)上增加了平衡限制,控制每個(gè)節(jié)點(diǎn)的左右子樹高度差不大于1,使得二叉樹的高度不會(huì)太高,提高了插入、查找和刪除操作的效率。6.6.2TreeSet集合二叉樹中元素的存儲(chǔ)結(jié)構(gòu)。6.6.2TreeSet集合TreeSet集合采用二叉樹結(jié)構(gòu)存儲(chǔ)元素的特殊性質(zhì),使得集合中的元素可以根據(jù)某種規(guī)則進(jìn)行排序。對于包含String、Integer等Java提供的基本數(shù)據(jù)類型的元素,它們已經(jīng)具備默認(rèn)的排序規(guī)則,因此可以直接排序。6.6.2TreeSet集合案例演示下面通過一個(gè)案例演示在TreeSet集合中存儲(chǔ)Integer類型的數(shù)據(jù)。Example10.java源代碼6.6.2TreeSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.6.2TreeSet集合TreeSet集合為什么能對Integer類型的元素排序呢6.6.2TreeSet集合TreeSet集合之所以能夠?qū)nteger類型的數(shù)據(jù)進(jìn)行排序,是因?yàn)镮nteger類、String類以及其他基本類型的包裝類都實(shí)現(xiàn)了Comparable接口。在比較元素大小時(shí),TreeSet會(huì)調(diào)用其重寫Comparable接口的compareTo()方法,根據(jù)元素類型和實(shí)際情況比較元素的大小,實(shí)現(xiàn)對集合的整體排序,這種排序稱為類的自然排序。6.6.2TreeSet集合通常,compareTo()方法簽名的格式如下。publicintcompareTo(Tother){}T表示與當(dāng)前對象進(jìn)行比較的對象類型。compareTo()方法會(huì)返回一個(gè)int類型的整數(shù)值來表示對象之間的大小關(guān)系。如果當(dāng)前對象小于other對象,則返回一個(gè)負(fù)整數(shù)。果當(dāng)前對象大于other對象,則返回一個(gè)正整數(shù)。如果兩個(gè)對象相等,則返回0。6.6.2TreeSet集合如果想讓自定義對象也能排序,則可以讓自定義類實(shí)現(xiàn)Comparable接口,并在重寫的comparaTo()方法中定義自定義對象之間的比較規(guī)則。例如,根據(jù)對象的特定屬性或者其他需要比較的標(biāo)準(zhǔn),來確定對象的大小關(guān)系。6.6.2TreeSet集合案例演示下面通過一個(gè)案例演示在TreeSet集合中存儲(chǔ)自定義對象,案例要求存儲(chǔ)學(xué)生對象并根據(jù)學(xué)生的年齡升序排序,當(dāng)年齡相同時(shí)按照姓名的升序排序。Example11.java源代碼6.6.2TreeSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.6.2TreeSet集合除了前面介紹的自然排序外,TreeSet集合還有另一種實(shí)現(xiàn)排序的方式,即讓TreeSet集合實(shí)現(xiàn)Comparator接口,并重寫compare()方法,這種排序方式稱為自定義排序。compare()方法的返回值規(guī)則與compareTo()方法相同。6.6.2TreeSet集合案例演示下面修改文件Example11.java,通過自定義排序的方式實(shí)現(xiàn)相同的功能。首先定義學(xué)生類Student。Student.java源代碼6.6.2TreeSet集合案例演示下面定義測試類,將學(xué)生對象通過自定義排序的方式存入TreeSet集合。Example12.java源代碼6.6.2TreeSet集合案例演示案例的運(yùn)行結(jié)果如下圖所示?!景咐?-2】國慶抽獎(jiǎng)活動(dòng)案例描述為了引流促銷,某商場在國慶期間開展抽獎(jiǎng)活動(dòng),活動(dòng)期間每5名顧客參與就會(huì)啟動(dòng)一次抽獎(jiǎng),并在5名顧客中隨機(jī)抽取3名顧客作為幸運(yùn)顧客贈(zèng)送商場消費(fèi)券,抽獎(jiǎng)的其他要求如下。參與的顧客需要填寫姓名和手機(jī)號作為抽獎(jiǎng)憑證。已參與的顧客不得重復(fù)參與抽獎(jiǎng)活動(dòng)。幸運(yùn)顧客按照姓名升序排序,姓名相同的幸運(yùn)顧客則繼續(xù)根據(jù)手機(jī)尾號升序排序。顧客參與抽獎(jiǎng)時(shí),唯一識別顧客身份的是顧客的姓名和微信號?!景咐?-2】國慶抽獎(jiǎng)活動(dòng)案例效果Map集合6.76.7Map集合現(xiàn)實(shí)生活中,每個(gè)人都有唯一的身份證號,通過身份證號可以快速查找到這個(gè)人的信息,這兩者是一對一的關(guān)系。在Java程序中,如果想要存儲(chǔ)這種具有對應(yīng)關(guān)系的數(shù)據(jù),可以使用Map集合,Map集合常用的實(shí)現(xiàn)類有HashMap集合和TreeMap集合,下面對Map集合的相關(guān)內(nèi)容進(jìn)行講解。6.7.1Map集合簡介掌握Map集合的作用,能夠簡述Map集合常用的方法以及常用實(shí)現(xiàn)類的特點(diǎn)

先定一個(gè)小目標(biāo)!6.7.1Map集合簡介Map集合是Java中用于存儲(chǔ)和操作鍵值對的數(shù)據(jù)結(jié)構(gòu),其中的每個(gè)元素都包含一個(gè)鍵對象key和一個(gè)值對象value,它們之間是一對一的映射關(guān)系。Map集合中的鍵不允許重復(fù),而值可以重復(fù)。6.7.1Map集合簡介Map集合定義了很多雙列集合通用的集合操作方法,包括添加、刪除和判斷元素等一些基本方法,還針對雙列集合的特殊結(jié)構(gòu)提供了基于鍵和值的獲取方法。常用方法如下所示。方法聲明功能描述Vput(Kkey,Vvalue)向Map集合中添加元素(鍵值對),如果當(dāng)前Map集合中已有一個(gè)鍵值對中的鍵與key相等,則新的鍵值對會(huì)覆蓋原來的鍵值對Vremove(Objectkey)從Map集合中刪除鍵為key的鍵值對,并返回key對應(yīng)的value;如果該key不存在,則返回nullvoidclear()移除Map集合中所有鍵值對元素booleancontainsKey(Objectkey)查詢Map集合中是否包含指定key的鍵值對,如果包含則返回true6.7.1Map集合簡介接上頁表格。方法聲明功能描述booleancontainsValue(Objectvalue)查詢Map集合中是否包含指定value的鍵值對,如果包含則返回truebooleanisEmpty()判斷Map集合是否為空intsize()返回集合中元素的數(shù)量Vget(Objectkey)返回Map集合中指定鍵所映射的值,V表示值的數(shù)據(jù)類型。如果不包含則返回nullSet<K>keySet()返回Map集合中所有鍵對象的Set集合Collection<V>values()返回Map集合中所有值對象組成的Collection集合Set<Map.Entry<K,V>>entrySet()返回Map集合中所有鍵值對的Set集合6.7.2HashMap集合掌握HashMap集合的使用,能夠使用HashMap實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.7.2HashMap集合案例演示HashMap集合的底層結(jié)構(gòu)與HashSet類似,也是采用哈希表來存儲(chǔ)元素。HashMap集合中的大部方法都是Map集合方法的實(shí)現(xiàn),下面先通過一個(gè)獲取文具價(jià)格的案學(xué)習(xí)HashMap集合的使用。Example13.java源代碼6.7.2HashMap集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.7.2HashMap集合在程序開發(fā)中,對于Map集合的遍歷操作也是非常常見的需求,通常有以下兩種遍歷方式。第一種是先通過keySet()方法獲取到Map集合中所有鍵的集合,再通過get()方法獲取每個(gè)鍵所對應(yīng)的值。第二種是將每個(gè)鍵值對看作一個(gè)對象,通過entrySet()方法獲取Map集合中所有鍵值對對象的Set集合,再遍歷Set集合。6.7.2HashMap集合案例演示下面通過一個(gè)案例演示前面講解的兩種遍歷Map集合的方式。Example14.java源代碼6.7.2HashMap集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.7.2HashMap集合HashMap集合中元素的存取順序不一致,如果想要元素的添加順序和輸出順序一致,可以使用LinkedHashMap類,它是HashMap的一個(gè)子類,其原理與LinkedHashSet相同,通過在內(nèi)部使用雙向鏈表來維護(hù)元素的添加順序。6.7.2HashMap集合案例演示下面使用LinkedHashMap集合存儲(chǔ)數(shù)據(jù)并進(jìn)行遍歷。Example15.java源代碼6.7.2HashMap集合案例演示案例的運(yùn)行結(jié)果如下圖所示。6.7.3TreeMap集合掌握TreeMap集合的使用,能夠使用TreeMap實(shí)現(xiàn)數(shù)據(jù)的增刪改查

先定一個(gè)小目標(biāo)!6.7.3TreeMap集合TreeMap是Map集合的一個(gè)實(shí)現(xiàn)類,它的底層與TreeSet集合類似,采用平衡二叉樹的結(jié)構(gòu)存儲(chǔ)數(shù)據(jù),并通過二叉樹的特性保證集合中鍵的唯一性。TreeMap集合同樣可以依賴自然排序或者自定義排序?qū)现械逆I進(jìn)行排序。6.7.3TreeMap集合案例演示下面通過一個(gè)案例來演示TreeMap集合的用法。案例要求在TreeMap集合中存儲(chǔ)學(xué)生類對象為鍵,學(xué)生的班級為對應(yīng)的值的鍵值對集合,學(xué)生對象包含姓名和成績兩個(gè)屬性,要求遍歷Map集合并根據(jù)成績降序排序,其次根據(jù)姓名升序排序。首先定義學(xué)生類Student.java。Student.java源代碼6.7.3TreeMap集合案例演示下面定義測試類,將學(xué)生對象和學(xué)生的班級以鍵值對的方式存入TreeMap集合中。Example16.java源代碼6.7.3TreeMap集合案例演示案例的運(yùn)行結(jié)果如下圖所示。【案例6-3】英漢互譯案例描述本案例要求編寫一個(gè)程序,模擬英漢互譯的操作。首先程序會(huì)初始化n組對應(yīng)的中英文翻譯數(shù)據(jù),每個(gè)英文單詞有1個(gè)或多個(gè)中文翻譯,一個(gè)中文詞語也可能有多個(gè)英文翻譯。用戶輸入英文單詞或中文詞語后,程序輸出該單詞或詞語所有對應(yīng)的中文翻譯或英文翻譯,若未搜索到該單詞或詞語,則給出相應(yīng)的提示?!景咐?-3】英漢互譯案例效果【案例6-4】益智棋牌游戲案例描述棋牌游戲相信許多人都玩過。本案例要求編寫一個(gè)程序模擬棋牌游戲洗牌發(fā)牌的過程。該游戲使用一副54張的撲克牌,牌面由花色和數(shù)字(字母)組成,花色有四種,分別表示黑桃、紅桃、方片和梅花,小?和大?分別表示小王和大王。該游戲共有3位玩家參與,首先將這54張牌的順序打亂每人輪流摸一次牌,剩余3張留作底牌,然后在控制臺(tái)打印3位玩家的牌和3張底牌?!景咐?-4】益智棋牌游戲案例描述本案例中洗牌的步驟需要把54張牌的順序打亂,可以使用一個(gè)方法shuffle(),它可以用來打亂集合中元素的順序。該方法是在java.utils.Collections類中定義的,具體用法如下。上述方法的參數(shù)表示要打亂的集合,該方法沒有返回值。打亂操作會(huì)在原始集合上進(jìn)行。Collections.shuffle(Listlist);【案例6-4】益智棋牌游戲案例效果Stream流6.86.8Stream流熟悉Stream流的使用,能夠使用Stream流對集合進(jìn)行各種操作

先定一個(gè)小目標(biāo)!6.8Stream流Stream流又稱StreamAPI,是JDK8開始提供的用于處理數(shù)據(jù)的API,它將待處理的數(shù)據(jù)視為流,在管道中傳輸。使用Stream流可以輕松地對數(shù)組和集合進(jìn)行操作,簡化集合和數(shù)組的遍歷、篩選、過濾等操作。此外,Stream流的操作會(huì)產(chǎn)生結(jié)果,但不會(huì)修改數(shù)據(jù)源,這使得數(shù)據(jù)的處理更加安全可靠。6.8Stream流使用Stream流處理集合一般需要經(jīng)過三個(gè)步驟,分別是獲取Stream流、使用中間方法對流進(jìn)行處理、使用終結(jié)方法獲取處理結(jié)果。下面對這三個(gè)步驟進(jìn)行說明。6.8Stream流1.獲取Stream流獲取Stream流指的是從數(shù)據(jù)源中獲取Stream流的引用,讓開發(fā)者能夠?qū)?shù)據(jù)源進(jìn)行流式處理。在Java中,對于所有的單列集合,Collection集合提供了一個(gè)stream()方法,用于獲取對應(yīng)集合的Stream流對象。對于Java中的雙列集合,無法直接使用Stream流進(jìn)行處理。但是可以通過keySet()方法或entrySet()方法將雙列集合轉(zhuǎn)為單列集合,然后調(diào)用stream()方法獲取Stream流。6.8Stream流2.Stream流的中間方法獲取到集合的Stream流后,就可以對流中的數(shù)據(jù)進(jìn)行操作了。Stream流提供了一系列方法,用于對數(shù)據(jù)流進(jìn)行過濾、排序、去重等中間操作,這些方法被稱為中間方法。中間方法是對Stream流中的元素執(zhí)行處理操作的方法,不會(huì)立即返回最終的結(jié)果流,它們在終結(jié)方法被調(diào)用時(shí)才會(huì)執(zhí)行。

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論