![Java程序設(shè)計(jì)(第3版) 課件 -第四部分 核心API的使用_第1頁(yè)](http://file4.renrendoc.com/view12/M08/3D/3C/wKhkGWb0ypGADKdKAAC0l2UeIjw373.jpg)
![Java程序設(shè)計(jì)(第3版) 課件 -第四部分 核心API的使用_第2頁(yè)](http://file4.renrendoc.com/view12/M08/3D/3C/wKhkGWb0ypGADKdKAAC0l2UeIjw3732.jpg)
![Java程序設(shè)計(jì)(第3版) 課件 -第四部分 核心API的使用_第3頁(yè)](http://file4.renrendoc.com/view12/M08/3D/3C/wKhkGWb0ypGADKdKAAC0l2UeIjw3733.jpg)
![Java程序設(shè)計(jì)(第3版) 課件 -第四部分 核心API的使用_第4頁(yè)](http://file4.renrendoc.com/view12/M08/3D/3C/wKhkGWb0ypGADKdKAAC0l2UeIjw3734.jpg)
![Java程序設(shè)計(jì)(第3版) 課件 -第四部分 核心API的使用_第5頁(yè)](http://file4.renrendoc.com/view12/M08/3D/3C/wKhkGWb0ypGADKdKAAC0l2UeIjw3735.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第四部分核心API的使用第15章集合框架泛型快速入門泛型(GenericType)是JDK5.0版本增加的特性。泛型對(duì)學(xué)習(xí)Java集合是非常重要的知識(shí)點(diǎn),Java類的屬性、方法參數(shù)及方法返回值都需要指定數(shù)據(jù)類型。泛型的本質(zhì)是參數(shù)化類型,也就是將數(shù)據(jù)類型作為一個(gè)參數(shù)來(lái)處理。具體來(lái)說(shuō),泛型就是在Java類中需要指定數(shù)據(jù)類型的地方不指定具體的類型,而是用一個(gè)參數(shù)替代,具體使用時(shí)再指定其具體類型。集合對(duì)象可以持有其他對(duì)象,作為數(shù)據(jù)容器使用,與數(shù)組的功能類似。JavaAPI中的集合框架都位于java.util包中,實(shí)現(xiàn)了很多常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),如鏈表、隊(duì)列、哈希表等。本章將介紹Java語(yǔ)言的集合框架。Java集合框架概述Java集合框架是由很多接口、抽象類、具體類組成的,都位于java.util包中。集合接口定義了具體集合類的規(guī)范。1.Collection<E>接口Collection接口是所有集合類的根接口,是一個(gè)泛型接口。Collection對(duì)象可以持有任何類型的對(duì)象,其持有的對(duì)象稱為集合元素。Collection接口中定義了add(Eo)方法,可以將對(duì)象存儲(chǔ)到Collection對(duì)象中。Collection接口還有很多子接口,每個(gè)子接口有不同的特征。2.Map<K,V>接口Map接口是Java集合框架中的另一個(gè)關(guān)鍵類型,即映射接口,也是一個(gè)泛型接口。Map對(duì)象中映射了key值和value值,key值不允許重復(fù)。Collection對(duì)象只能持有單個(gè)對(duì)象;而Map對(duì)象持有的是兩個(gè)對(duì)象的映射關(guān)系,提供了put(Kkey,Vvalue)方法來(lái)存儲(chǔ)鍵值對(duì)。例如,在Map對(duì)象中存儲(chǔ)員工與部門的映射關(guān)系,那么員工將作為Map的key,對(duì)應(yīng)的部門作為Map的value。3.Iterator<E>接口集合對(duì)象作為數(shù)據(jù)容器使用,用來(lái)持有其他對(duì)象,很多時(shí)候需要對(duì)集合元素進(jìn)行遍歷。Iterator接口提供了遍歷Collection對(duì)象的功能,也是一個(gè)泛型接口。對(duì)于Map對(duì)象,不能直接使用Iterator遍歷,但是Map接口中提供了將key與value分別轉(zhuǎn)變成Collection對(duì)象的方法,然后就可以使用Iterator接口分別遍歷Map的key與value。第15章集合框架Iterator接口實(shí)際應(yīng)用中,常常需要對(duì)集合元素進(jìn)行迭代。Iterator接口提供了迭代集合對(duì)象中元素的功能。Iterator接口的主要方法如下。1.booleanhasNext()此方法用來(lái)判斷被迭代的集合中是否存在元素,若集合中存在至少一個(gè)元素,則返回true,否則返回false。該方法的返回值往往用來(lái)作為while循環(huán)的條件來(lái)迭代集合。2.Enext()此方法用來(lái)返回集合中的當(dāng)前元素,E是泛型,具體類型根據(jù)集合的泛型類型決定。要使用Iterator接口迭代集合對(duì)象,首先必須把集合對(duì)象轉(zhuǎn)換成Iterator對(duì)象。第15章集合框架Collection接口及其子接口Collection接口定義了集合類型的基本規(guī)范。Collection接口中常用的方法如下。(1)booleanadd(Eo):可以向Collection對(duì)象中存儲(chǔ)對(duì)象o,o的類型是泛型E。(2)Iterator<E>iterator():生成迭代器對(duì)象,進(jìn)而可以迭代集合中的元素。(3)intsize():返回集合對(duì)象中元素的個(gè)數(shù)。其中,size指的是有效長(zhǎng)度,即添加到集合中的元素個(gè)數(shù)。集合中還有一個(gè)概念是容量(capacity),容量與數(shù)組的長(zhǎng)度類似,指的是集合當(dāng)前能夠容納的元素的個(gè)數(shù)。集合的容量是可變的,而數(shù)組的長(zhǎng)度是不可變的。Collection接口定義了集合類型的基本規(guī)范,集合框架中基于Collection接口衍生了3個(gè)主要的子接口,每個(gè)子接口規(guī)范一種具體的集合類型,分別是列表(List)、集合(Set)和隊(duì)列(Queue)。1.ListList稱為列表,是有序的(ordered)集合,其中的元素都是有索引的。List接口是Collection接口的子接口,所以具有Collection接口中定義的所有功能。同時(shí),List接口擴(kuò)展了一些新的方法,新方法大多與索引有關(guān),作用如下。(1)voidadd(intindex,Eelement):將元素插入指定索引位置。(2)Eget(intindex):將集合中某索引位置的元素取出并返回。(3)Eset(intindex,Eelement):使用某元素替換集合中指定索引位置的元素。2.SetSet稱為集合,與List不同的是,Set是無(wú)序的,但是不允許存儲(chǔ)重復(fù)元素,而List中允許存儲(chǔ)重復(fù)元素。Set接口是Collection接口的子接口,所以具有Collection接口中定義的所有功能。Set接口幾乎沒(méi)有擴(kuò)展新方法。
3.QueueQueue稱為隊(duì)列,是JDK5.0版本增加的接口,實(shí)現(xiàn)了“先進(jìn)先出”(FIFO)的存儲(chǔ)結(jié)構(gòu)。Queue接口是Collection接口的子接口,具有Collection接口中定義的所有功能。此外,Queue接口還提供了一些新的插入、提取、查詢等方法。第15章集合框架List接口的實(shí)現(xiàn)類List是有序的集合,實(shí)際開(kāi)發(fā)中使用較多。List是接口,無(wú)法直接創(chuàng)建對(duì)象。1.ArrayListArrayList稱為數(shù)組列表,數(shù)據(jù)采用數(shù)組的方式存儲(chǔ),使用連續(xù)內(nèi)存存儲(chǔ)。ArrayList類是Java語(yǔ)言中可變長(zhǎng)度數(shù)組的實(shí)現(xiàn),是最常用的集合類型之一。2.LinkedListLinkedList稱為鏈表,表示該集合類型實(shí)現(xiàn)了“鏈表”的數(shù)據(jù)結(jié)構(gòu)。值得一提的是,LinkedList類不僅實(shí)現(xiàn)了List接口,還實(shí)現(xiàn)了Queue接口,可以說(shuō)鏈表同時(shí)也可以作為一個(gè)隊(duì)列對(duì)象使用,使用方式與ArrayList類類似。3.VectorVector類“歷史悠久”,是JDK1.0版本中的集合類,后來(lái)經(jīng)過(guò)修改實(shí)現(xiàn)了List接口。Vector類的功能幾乎都可以被ArrayList類替代,主要區(qū)別是Vector類是線程同步的,而ArrayList類不是同步的。第15章集合框架Set接口的實(shí)現(xiàn)類Set接口是Collection另一個(gè)重要的子接口,主要特點(diǎn)是其中的元素不允許重復(fù),即Set中的元素都是唯一的。1.HashSetHashSet類是Set接口的一個(gè)主要實(shí)現(xiàn)類,底層是哈希表結(jié)構(gòu)。2.TreeSetTreeSet類是Set接口的另一個(gè)實(shí)現(xiàn)類。實(shí)際上,TreeSet類沒(méi)有直接實(shí)現(xiàn)Set接口,而是實(shí)現(xiàn)了Set接口的一個(gè)子接口SortedSet。TreeSet不但能夠保證其中的元素不重復(fù),而且能對(duì)元素進(jìn)行排序。TreeSet中的元素對(duì)象所屬的類必須實(shí)現(xiàn)Comparable接口,否則默認(rèn)排序時(shí)將拋出運(yùn)行期異常ClassCastException。下面修改Department類,使其實(shí)現(xiàn)Comparable接口,覆蓋compareTo方法。第15章集合框架Map接口的實(shí)現(xiàn)類Map與Collection不同,Map中保存的是鍵值對(duì),key值不允許重復(fù),而Collection中保存的是單個(gè)對(duì)象。Map接口中的主要方法如下。(1)Vput(Kkey,Vvalue)。該方法可以將key和value存到Map對(duì)象中。如果key已經(jīng)存在,則被覆蓋,返回被覆蓋前的value;如果key不存在,則返回null。(2)Vget(Objectkey)。該方法可以根據(jù)key返回對(duì)應(yīng)的value。(3)intsize()。該方法返回Map對(duì)象中鍵值對(duì)的數(shù)量。(4)Set<K>keySet()。該方法將Map對(duì)象中的key值取出,返回Set對(duì)象中。(5)Collection<V>values()。該方法將Map對(duì)象中的value值取出,返回Collection對(duì)象中。第15章集合框架第15章集合框架Collections類java.util包中提供了一個(gè)集合框架的工具類:Collections類。與Arrays類(數(shù)組工具類)類似,Collections類中的所有方法都是靜態(tài)方法,都可以直接使用Collections類名調(diào)用。1.同步集合對(duì)象的方法集合框架的具體實(shí)現(xiàn)類中,Vector和Hashtable類是線程同步的,而其他集合類都不是線程同步的。如果需要將集合類做成線程同步的類,可以調(diào)用Collections類中相應(yīng)的synchronizedXxx方法實(shí)現(xiàn)。如publicstatic<T>List<T>synchronizedList(List<T>list)方法可以將List對(duì)象同步。2.對(duì)List排序的方法集合接口中的Set和Map接口都有可以排序的實(shí)現(xiàn)類,如TreeSet、TreeMap。而List接口沒(méi)有可以排序的實(shí)現(xiàn)類。如果要對(duì)List進(jìn)行排序,可以使用Collections類中的方法,代碼如下:Collections中還有很多其他方法,均是集合類的工具方法,如二分查找、返回集合中的最大/最小值等。使用Collections中的方法時(shí)涉及大量的泛型語(yǔ)法,可參考泛型章節(jié)。集合與數(shù)組之間的轉(zhuǎn)換由于數(shù)組的性能和效率比集合高,所以在實(shí)際應(yīng)用中可能需要將集合對(duì)象轉(zhuǎn)換成數(shù)組對(duì)象進(jìn)行下一步操作。Collection接口中定義了集合與數(shù)組之間的轉(zhuǎn)換方法,代碼如下:其中,T是集合對(duì)象的泛型,a是一個(gè)已經(jīng)存在的數(shù)組,如果數(shù)組a的長(zhǎng)度小于集合的元素個(gè)數(shù),則重新創(chuàng)建一個(gè)新的數(shù)組來(lái)容納集合元素;如果數(shù)組a的長(zhǎng)度大于集合的元素個(gè)數(shù),則直接將集合元素復(fù)制到數(shù)組中。第15章集合框架File類要對(duì)文件進(jìn)行輸入/輸出操作,首先需要將文件封裝為對(duì)象。API中定義了File類來(lái)封裝文件。File類是java.io包中一個(gè)非常重要的類,可以協(xié)助進(jìn)行輸入/輸出操作。File的字面含義為“文件”,但既可以表示“文件”,也可以表示“目錄”。API中沒(méi)有Directory類,文件和目錄都使用File類進(jìn)行封裝。File類中定義了操作文件和目錄的方法。如以下代碼:第16章輸入/輸出系統(tǒng)文件過(guò)濾器在實(shí)際應(yīng)用中,常常只需要返回符合某些條件的子目錄及文件,即對(duì)目錄下的子目錄及文件進(jìn)行過(guò)濾。java.io包中提供了文件名過(guò)濾器及文件過(guò)濾器,可以對(duì)目錄下的子目錄及文件進(jìn)行過(guò)濾,只返回符合過(guò)濾條件的子目錄及文件。1.文件名過(guò)濾器FilenameFilter文件名過(guò)濾器FilenameFilter是一個(gè)接口,定義了設(shè)置過(guò)濾條件的方法accept(Filedir,Stringname),其中dir是當(dāng)前目錄,name是當(dāng)前子目錄或文件名。File類中提供了一個(gè)使用文件名過(guò)濾器遍歷目錄的方法publicString[]list(FilenameFilterfilter)。要想能夠使用指定的文件名過(guò)濾器過(guò)濾目錄,首先需要自定義一個(gè)文件名過(guò)濾器類,實(shí)現(xiàn)文件名過(guò)濾器接口FilenameFilter,覆蓋接口中的accept(Filedir,Stringname)方法,在該方法中定義過(guò)濾條件。File類中的list方法將目錄下的File對(duì)象逐一傳遞給accept方法,如果accept方法的返回值為true,則當(dāng)前的File對(duì)象包含在返回值數(shù)組中;如果返回值為false,則該File對(duì)象不包含在返回值數(shù)組中。2.文件過(guò)濾器FileFilter除了可以使用FilenameFilter針對(duì)名稱進(jìn)行過(guò)濾,還可以使用FileFilter進(jìn)行更為靈活的過(guò)濾。File類中提供了publicFile[]listFiles(FileFilterfilter)方法,可以使用FileFilter進(jìn)行過(guò)濾。使用FileFilter與使用FilenameFilter類似,首先必須自定義文件過(guò)濾器類,實(shí)現(xiàn)文件過(guò)濾器接口FileFilter,覆蓋其中的accept方法,定義過(guò)濾條件。第16章輸入/輸出系統(tǒng)I/O流的分類1.輸入流和輸出流I/O即輸入/輸出,輸入是對(duì)數(shù)據(jù)進(jìn)行“讀(read)”操作,從外存讀到內(nèi)存,稱為“入”;輸出是對(duì)數(shù)據(jù)進(jìn)行“寫(write)”操作,從內(nèi)存寫到外存,稱為“出”。從輸入/輸出這個(gè)角度,可以將I/O流類分為兩大類,即輸入流和輸出流,輸入流定義了讀數(shù)據(jù)的方法,輸出流定義了寫數(shù)據(jù)的方法。I/O流類中的所有輸入流都是InputStream類或Reader類的子類。凡是類名以InputStream結(jié)尾的類都是InputStream類的子類,如FileInputStream等;同樣,凡是類名以Reader結(jié)尾的類都是Reader類的子類,如FileReader等。I/O流類中的所有輸出流都是OutputStream類或Writer類的子類。凡是類名以O(shè)utputStream結(jié)尾的類都是OutputStream類的子類,如FileOutputStream等;同樣,凡是類名以Writer結(jié)尾的類都是Writer類的子類,如FileWriter等。2.字節(jié)流和字符流I/O流進(jìn)行數(shù)據(jù)輸入/輸出操作時(shí),編碼格式有8位字節(jié)和16位字符兩種。所以從數(shù)據(jù)流編碼格式角度劃分,I/O流類又可以分為字節(jié)流和字符流兩大類。InputStream類和OutputStream類的子類都是字節(jié)流,都將數(shù)據(jù)按照8位的字節(jié)方式傳輸,往往應(yīng)用于視頻、音頻等文件的讀/寫操作。Reader類和Writer類的子類都是字符流,都將數(shù)據(jù)按照16位的字符方式傳輸,往往用于文本文件的讀/寫,尤其是包含漢字的文件,必須使用字符流讀/寫。3.節(jié)點(diǎn)流和處理流要使用I/O流類進(jìn)行數(shù)據(jù)輸入/輸出操作,必須先創(chuàng)建I/O流類的對(duì)象。而創(chuàng)建I/O流對(duì)象,必須使用I/O流類的構(gòu)造方法。下面比較字符輸入流FileReader和BufferedReader的構(gòu)造方法。(1)publicFileReader(Filefile)。FileReader類的構(gòu)造方法參數(shù)是File類型,也就是說(shuō)FileReader對(duì)象直接封裝File對(duì)象。(2)publicBufferedReader(Readerin)。BufferedReader類的構(gòu)造方法參數(shù)是Reader類型對(duì)象,也就是說(shuō)BufferedReader可以封裝任意一種Reader類型對(duì)象,如FileReader、StringReader等。第16章輸入/輸出系統(tǒng)I/O編程了解I/O包的結(jié)構(gòu)后,本節(jié)將通過(guò)一個(gè)例子介紹如何使用I/O流進(jìn)行輸入/輸出操作。例如,在控制臺(tái)上輸出文件“MyFilenameFilter.java”的內(nèi)容,實(shí)現(xiàn)步驟如下。1.確定需要進(jìn)行輸入/輸出操作的數(shù)據(jù)源2.選擇使用輸入流或輸出流3.選擇使用字節(jié)流或字符流4.選擇合適的節(jié)點(diǎn)流5.判斷是否需要使用處理流6.調(diào)用I/O流中的方法進(jìn)行讀/寫操作7.在finally塊中關(guān)閉流對(duì)象第16章輸入/輸出系統(tǒng)GUI編程概述1.AWTAWT是Java語(yǔ)言中的原始GUI工具包,相關(guān)API位于java.awt包中。AWT是一個(gè)組件非常有限的GUI工具包,不支持樹(shù)、表格等。大部分情況下,可以在一臺(tái)計(jì)算機(jī)上開(kāi)發(fā)和測(cè)試Java代碼(如Windows平臺(tái)),然后不經(jīng)測(cè)試就可以在其他平臺(tái)(如Linux平臺(tái))上運(yùn)行。然而AWT無(wú)法實(shí)現(xiàn),AWT運(yùn)行時(shí),每個(gè)組件都要依賴于當(dāng)前平臺(tái)的GUI對(duì)等體(peer)控件,因此,AWTGUI的外觀和行為就會(huì)依賴當(dāng)前平臺(tái)。2.SwingJavaSwing是JavaFoundationClasses(JFC)的一部分,是在AWT基礎(chǔ)上發(fā)展而來(lái)的GUIAPI,都存在于javax.swing包中,作用是解決AWT的缺點(diǎn)。比起AWT,Swing的組件豐富而強(qiáng)大,增加了很多組件,如樹(shù)、表格等。Swing甚至與后面要介紹的SWT比都毫不遜色。為了解決AWT對(duì)平臺(tái)的依賴性,Swing將對(duì)平臺(tái)的依賴降到了最低。只有窗口和框架之類的頂層組件使用平臺(tái)的對(duì)等體,大部分組件使用純Java代碼模擬,與平臺(tái)無(wú)關(guān)。Swing中,使用平臺(tái)對(duì)等體的組件稱為重量級(jí)(heavyweight)組件,Java代碼模擬的組件稱為輕量級(jí)(lightweight)組件。Swing允許在一個(gè)GUI應(yīng)用中混合使用輕量級(jí)和重量級(jí)組件。Swing中提供了不同的外觀,可以模擬不同平臺(tái)的效果。3.SWTAWT和Swing都是原Sun公司推出的JavaGUI工具包,而SWT是Eclipse組織為了開(kāi)發(fā)EclipseIDE環(huán)境所編寫的一組底層GUIAPI。SWT的設(shè)計(jì)者汲取了AWT和Swing兩者的優(yōu)點(diǎn),取得了很大的進(jìn)步。SWT提供了豐富的組件集,完全可以與Swing媲美。SWT是使用對(duì)等體實(shí)現(xiàn)的,不過(guò)對(duì)等體的工作方式與AWT不同。SWT程序?qū)嵸|(zhì)上就是一個(gè)當(dāng)前平臺(tái)的應(yīng)用程序。第17章GUI編程Swing中的組件wing的大部分組件類都是JComponent類的子類。例如,JButton是按鈕組件,JTextField是文本框組件,JTextArea是文本區(qū)域組件,JTable是表格組件等。有一種特殊的組件被稱為容器,容器中可以放置其他組件,如JFrame、JPanel都是容器。第17章GUI編程上述代碼中,聲明并創(chuàng)建了聊天室界面中需要使用的組件,其中包含兩個(gè)JButton按鈕組件,用來(lái)構(gòu)建Send和Quit按鈕;一個(gè)JTextField組件,用來(lái)輸入聊天信息;一個(gè)JTextArea組件,用來(lái)顯示聊天內(nèi)容;一個(gè)JPanel面板組件,用來(lái)作為兩個(gè)按鈕的容器,放置兩個(gè)按鈕;一個(gè)JFrame組件,用來(lái)構(gòu)建聊天室窗口。除了這些簡(jiǎn)單組件外,Swing還支持很多功能強(qiáng)大的組件,如JTable、JTree等。Swing中的布局要成功構(gòu)建一個(gè)GUI程序,首先要像第17.2節(jié)介紹的那樣創(chuàng)建所有需要的組件,然后根據(jù)設(shè)計(jì)對(duì)組件進(jìn)行布局。Java語(yǔ)言中的GUI使用布局管理器進(jìn)行布局,Swing與AWT工具包的布局管理器可以通用。第17章GUI編程1.FlowLayoutFlowLayout稱為流布局管理器。該管理器將組件按照從左到右、從上到下的自然順序布局。2.BorderLayoutBorderLayout稱為邊界布局管理器。該管理器將容器分為5個(gè)區(qū)域,分別用東、南、西、北、中5個(gè)方位表示。3.GridLayoutGridLayout稱為網(wǎng)格布局管理器。該管理器將容器分為大小相等的網(wǎng)格。4.CardLayoutCardLayout稱為卡片布局管理器。該管理器允許在一個(gè)位置放置多個(gè)組件。5.GridBagLayoutGridBagLayout稱為網(wǎng)袋布局管理器。該管理器是一個(gè)靈活、復(fù)雜的布局管理器。Swing中的事件處理GUI事件處理步驟第17章GUI編程1.確定事件源要進(jìn)行事件處理,首先要確定事件源,即發(fā)生事件的組件。例如,單擊Quit按鈕,事件源就是Quit按鈕;拖動(dòng)窗口,事件源就是窗口。2.確定事件類型確定事件源后,需根據(jù)要處理的事件確定事件類型。如單擊按鈕的事件類型是ActionEvent,關(guān)閉窗口的事件類型是WindowEvent。3.確定事件監(jiān)聽(tīng)器接口確定事件類型后,需要進(jìn)一步確定處理該事件的事件監(jiān)聽(tīng)器接口,如ActionEvent對(duì)應(yīng)的接口是ActionListener。確定接口后,需要自定義事件處理器類實(shí)現(xiàn)該接口。定義QuitHandler類實(shí)現(xiàn)ActionListener接口,作為處理Quit按鈕ActionEvent的處理器類。4.覆蓋事件監(jiān)聽(tīng)器接口中合適的方法自定義類實(shí)現(xiàn)事件監(jiān)聽(tīng)器接口后,需要覆蓋事件監(jiān)聽(tīng)器中特定的方法。事件監(jiān)聽(tīng)器接口中可能聲明了多個(gè)方法,事件處理機(jī)制會(huì)針對(duì)不同的用戶操作自動(dòng)調(diào)用不同的方法。在QuitHandler類中重寫ActionListener接口的actionPerformed方法,實(shí)現(xiàn)聊天室程序退出的功能。5.為事件源注冊(cè)事件監(jiān)聽(tīng)器實(shí)現(xiàn)事件監(jiān)聽(tīng)器后,需要為事件源注冊(cè)事件監(jiān)聽(tīng)器才能生效。每個(gè)組件都有一系列addXxxListener方法,可以用來(lái)為組件注冊(cè)不同的事件監(jiān)聽(tīng)器。例如,JButton類中定義了addActionListener方法,可以為JButton組件注冊(cè)ActionListener監(jiān)聽(tīng)器。修改ChatRoom類,為Quit按鈕注冊(cè)事件監(jiān)聽(tīng)器。使用內(nèi)部類進(jìn)行事件處理ava中的內(nèi)部類是外部類的一個(gè)成員,可以直接使用外部類的屬性和方法。在GUI事件處理過(guò)程中,常常用到內(nèi)部類。本節(jié)繼續(xù)對(duì)前面章節(jié)實(shí)現(xiàn)的聊天室進(jìn)行事件處理,實(shí)現(xiàn)發(fā)送消息的功能:在文本框中輸入聊天信息,單擊Send按鈕后,消息顯示到顯示聊天內(nèi)容的文本區(qū)域。事件源是Send按鈕,事件類型是ActionEvent,需要使用的事件監(jiān)聽(tīng)器為ActionListener。因此,首先需要定義一個(gè)類實(shí)現(xiàn)ActionListener接口,覆蓋其中的actionPerformed方法,實(shí)現(xiàn)發(fā)送消息的功能。然后,使用addActionListener方法為Send按鈕注冊(cè)事件監(jiān)聽(tīng)器。創(chuàng)建SendHandler類,實(shí)現(xiàn)ActionListener接口,覆蓋其中的actionPerformed方法,實(shí)現(xiàn)將文本框信息發(fā)送到文本區(qū)域的功能。第17章GUI編程使用匿名內(nèi)部類進(jìn)行事件處理如果只需要使用內(nèi)部類的一個(gè)對(duì)象,那么就可以在聲明類的同時(shí)創(chuàng)建該對(duì)象,而隱去該內(nèi)部類的名稱,這樣的內(nèi)部類稱為匿名內(nèi)部類。如以下代碼:上述代碼中使用匿名內(nèi)部類創(chuàng)建了sendHandler對(duì)象,并將該對(duì)象作為Send按鈕的事件處理器使用。匿名內(nèi)部類是沒(méi)有名稱的內(nèi)部類,在類聲明的同時(shí)創(chuàng)建對(duì)象,往往在某內(nèi)部類只需要一個(gè)對(duì)象的情況下使用。匿名內(nèi)部類的類體與內(nèi)部類的類體相同,也需要實(shí)現(xiàn)其接口的所有方法。匿名內(nèi)部類對(duì)象的類型使用其需要實(shí)現(xiàn)的接口或抽象類來(lái)聲明,如例子中使用ActionListener接口作為對(duì)象類型。進(jìn)一步思考,如果sendHandler對(duì)象也只在一處使用,那么也沒(méi)有必要聲明對(duì)象名,可以使用匿名內(nèi)部類的匿名對(duì)象。如以下代碼:第17章GUI編程GUI中的并發(fā)任務(wù)在GUI中,常常需要處理并發(fā)任務(wù)。例如,聊天室程序可以支持傳遞文件功能,而傳遞文件的同時(shí)可以繼續(xù)聊天。接下來(lái),修改前面章節(jié)的聊天室程序,增加一個(gè)Loop按鈕,單擊該按鈕后程序進(jìn)入死循環(huán),做簡(jiǎn)單的輸出。代碼如下:第17章GUI編程與線程有關(guān)的API1.Thread類JavaAPI中提供了與線程有關(guān)的類和接口,因此可以非常直觀地使用Java語(yǔ)言進(jìn)行多線程編程。與線程有關(guān)的API大多位于java.lang包中,本節(jié)先介紹常用的Thread類。Thread類即線程類,Thread類的對(duì)象即線程對(duì)象。Thread類中提供了很多方法,start方法和run方法是兩個(gè)基本的、常用的方法。(1)publicvoidstart()。該方法用來(lái)啟動(dòng)線程。創(chuàng)建一個(gè)線程對(duì)象后,必須啟動(dòng)該線程才能被調(diào)度。啟動(dòng)線程并不會(huì)導(dǎo)致線程馬上運(yùn)行,而是需要等到CPU的調(diào)度才能運(yùn)行。一個(gè)線程最多只能啟動(dòng)一次,線程運(yùn)行結(jié)束后不可能再次啟動(dòng)。(2)publicvoidrun()。該方法用來(lái)運(yùn)行線程。當(dāng)線程調(diào)用了start方法并得到CPU的時(shí)間片調(diào)度后,就會(huì)執(zhí)行run方法。然而,Thread類中的run方法的方法體是空的,所以使用前需要覆蓋run方法,在run方法中編寫該線程對(duì)象需要執(zhí)行的任務(wù)代碼。2.Runnable接口Runnable接口是Java線程API中常用的接口,該接口已經(jīng)被Thread類實(shí)現(xiàn)。接口中只有一個(gè)方法:publicvoidrun()。該接口的實(shí)現(xiàn)類需要覆蓋run方法,在run方法中編寫線程執(zhí)行的代碼。接口實(shí)現(xiàn)類的對(duì)象作為線程運(yùn)行對(duì)象存在。第18章多線程編程創(chuàng)建線程要編寫多線程應(yīng)用,首先要?jiǎng)?chuàng)建線程對(duì)象。Java語(yǔ)言中提供了創(chuàng)建線程對(duì)象的便捷方法,本節(jié)將詳細(xì)介紹兩種常用的創(chuàng)建Java線程對(duì)象的方法。1.繼承Thread類創(chuàng)建線程對(duì)象的第一種方式是創(chuàng)建一個(gè)子類繼承Thread類,覆蓋其中的run方法,Thread類的子類對(duì)象就是線程對(duì)象。如以下代碼:上述代碼中創(chuàng)建的子類ProducerThread繼承了Thread類,那么ProducerThread類的對(duì)象就是線程對(duì)象。代碼中創(chuàng)建了pt1和pt2兩個(gè)線程對(duì)象,并分別使用start方法啟動(dòng)。線程得到CPU時(shí)間片調(diào)度后,將運(yùn)行ProducerThread類的run方法,該方法輸出當(dāng)前執(zhí)行的線程名稱及產(chǎn)生的隨機(jī)數(shù)。部分運(yùn)行結(jié)果如下:第18章多線程編程創(chuàng)建線程2.實(shí)現(xiàn)Runnable接口第一種創(chuàng)建線程的方式是創(chuàng)建Thread類的子類,使用子類直接創(chuàng)建線程對(duì)象。第二種方式是實(shí)現(xiàn)Runnable接口,覆蓋其中的run方法。Runnable接口的實(shí)現(xiàn)類可以封裝線程運(yùn)行的數(shù)據(jù)和代碼,這種創(chuàng)建線程的方式使用Thread類的如下構(gòu)造方法:publicThread(Runnabletarget)。其中,構(gòu)造方法的參數(shù)類型是Runnable,即Runnable接口實(shí)現(xiàn)類的對(duì)象。首先,創(chuàng)建子類實(shí)現(xiàn)Runnable接口,覆蓋其中的run方法。代碼如下:上述代碼中使用Producer類實(shí)現(xiàn)Runnable接口,覆蓋接口中的run方法,實(shí)現(xiàn)線程運(yùn)行體代碼。接下來(lái)可以創(chuàng)建線程對(duì)象,啟動(dòng)線程。代碼如下:第18章多線程編程上述代碼中創(chuàng)建了p1和p2兩個(gè)Producer對(duì)象,封裝線程運(yùn)行的數(shù)據(jù)和方法。然后分別使用這兩個(gè)Producer對(duì)象創(chuàng)建t1和t2兩個(gè)線程對(duì)象。t1線程運(yùn)行時(shí)將使用p1對(duì)象的屬性和方法,而t2線程運(yùn)行時(shí)將使用p2對(duì)象的屬性和方法。部分運(yùn)行結(jié)果如下:第18章多線程編程線程同步Java語(yǔ)言提供了關(guān)鍵字synchronized(同步)來(lái)完成此功能,稱為給對(duì)象加鎖,以保證操作共享對(duì)象的代碼同一時(shí)刻只被一個(gè)線程訪問(wèn)。下面介紹synchronized關(guān)鍵字的兩種使用方式。1.Synchronized關(guān)鍵字修飾代碼塊synchronized關(guān)鍵字可以修飾代碼塊,使該代碼塊成為同步塊。語(yǔ)法如下:2.Synchronized關(guān)鍵字修飾方法Synchronized關(guān)鍵字可以直接修飾方法,使方法成為同步方法。如以下代碼:第18章多線程編程線程通信如果多個(gè)線程共享某些數(shù)據(jù),為了避免共享數(shù)據(jù)被破壞,可以使用synchronized關(guān)鍵字對(duì)線程進(jìn)行同步。但是,有時(shí)某個(gè)線程必須等待另一個(gè)線程中的某些條件滿足才能執(zhí)行,那么線程之間就需要通信。線程通信的方法在Object類中定義。需要注意的是,線程通信的方法必須在同步塊中使用。實(shí)現(xiàn)線程通信的方法主要有以下幾個(gè)。1.wait方法如果某個(gè)對(duì)象調(diào)用了wait方法,那么該線程被阻塞,處于等待狀態(tài),且釋放其占用的鎖。語(yǔ)法如下:2.notify方法notify方法可以喚醒某個(gè)等待的線程。如果有多個(gè)等待的線程,到底會(huì)喚醒哪個(gè)不能確定,由JVM決定。語(yǔ)法如下:3.notifyAll方法notifyAll方法可以喚醒所有等待的線程,但是并不意味著所有被喚醒的線程都能馬上運(yùn)行wait后的代碼。被喚醒的線程需要得到對(duì)象的鎖,才可能在被調(diào)度后運(yùn)行wait后的代碼。語(yǔ)法如下:第18章多線程編程Thread類的方法1.start方法start方法是啟動(dòng)線程的方法。啟動(dòng)線程后,線程需要等到CPU調(diào)度才能運(yùn)行。2.run方法run方法是線程運(yùn)行時(shí)調(diào)用的方法,只有當(dāng)線程被CPU調(diào)度了,才會(huì)自動(dòng)執(zhí)行run方法。可以通過(guò)繼承Thread類,或者實(shí)現(xiàn)Runnable接口的方式,覆蓋對(duì)象中的run方法,實(shí)現(xiàn)線程運(yùn)行體。3.currentThread方法該方法是Thread類的靜態(tài)方法,可以使用Thread類名直接調(diào)用,返回正在運(yùn)行的線程引用。4.sleep(longmillis)方法該方法是使線程休眠的方法,方法參數(shù)是線程休眠的時(shí)長(zhǎng)。當(dāng)該休眠時(shí)間段結(jié)束時(shí),線程將“醒來(lái)”,重新等待調(diào)度。5.join方法join方法可以讓調(diào)用該方法的線程強(qiáng)行占有CPU資源,其他線程必須等待該線程運(yùn)行結(jié)束才可能被調(diào)度。join方法還有一個(gè)重載的方法:join(longmillis)。該方法可以使調(diào)用該方法的線程在指定時(shí)間內(nèi)強(qiáng)行占有資源,時(shí)間段結(jié)束后,該線程將不再有“特權(quán)”,與其他線程一起等待系統(tǒng)調(diào)度。6.yield方法yield方法可以使調(diào)用該方法的線程降低優(yōu)先級(jí),給其他線程機(jī)會(huì)。7.getPriority/setPriority方法線程都有優(yōu)先級(jí),可通過(guò)getPriority方法獲取優(yōu)先級(jí),也可通過(guò)setPriority方法設(shè)置優(yōu)先級(jí)。系統(tǒng)對(duì)線程的調(diào)度會(huì)參考線程的優(yōu)先級(jí)。第18章多線程編程線程死鎖在多線程應(yīng)用中都會(huì)存在死鎖問(wèn)題,Java語(yǔ)言的多線程也不例外。線程死鎖往往是因?yàn)槎嗑€程共享資源,而共享資源的加鎖順序不當(dāng)導(dǎo)致的。下面使用代碼演示線程死鎖問(wèn)題:第18章多線程編程DieLock1類繼承了Thread類,該類的對(duì)象就是線程對(duì)象,run方法中先對(duì)shareObj1加鎖,再對(duì)shareObj2加鎖。DieLock2類也繼承了Thread類,該類的對(duì)象也是一個(gè)線程對(duì)象,run方法中先對(duì)shareObj2加鎖,再對(duì)shareObj1加鎖,加鎖順序正好與DieLock1相反。代碼如下:第18章多線程編程使用以下代碼進(jìn)行測(cè)試:上述代碼中,創(chuàng)建了t1和t2兩個(gè)線程,分別是DieLock1和DieLock2類型。這兩個(gè)線程使用的屬性是相同的兩個(gè)字符串對(duì)象shareObj1和shareObj2。t1線程的run方法需要先獲取shareObj1的鎖,然后獲取shareObj2的鎖。而t2線程需要先獲取shareObj2的鎖,再獲取shareObj1的鎖。那么在運(yùn)行過(guò)程中,就可能出現(xiàn)以下結(jié)果:可見(jiàn)線程t1和t2陷入互相等待鎖的情況,都無(wú)法執(zhí)行下去,即發(fā)生死鎖。第18章多線程編程守護(hù)線程Java語(yǔ)言中的線程有兩種:守護(hù)(Daemon)線程和用戶線程。前面章節(jié)中的線程都是用戶線程,都是在程序中創(chuàng)建的。而守護(hù)線程有兩種來(lái)源,一種是Java虛擬機(jī)內(nèi)部創(chuàng)建的線程,即“在后臺(tái)執(zhí)行任務(wù)”的線程,如垃圾回收的線程就是守護(hù)線程;另一種是創(chuàng)建Thread對(duì)象后,通過(guò)調(diào)用Thread類的setDaemon方法,指定該線程是守護(hù)線程。守護(hù)線程是為用戶線程服務(wù)的,當(dāng)應(yīng)用中沒(méi)有任何用戶線程運(yùn)行時(shí),Java虛擬機(jī)將退出。第18章多線程編程TCP/IP概述要使用Java語(yǔ)言進(jìn)行基于TCP/IP的網(wǎng)絡(luò)編程,就有必要了解TCP/IP,本節(jié)將對(duì)TCP/IP進(jìn)行概述性介紹。TCP/IP是互聯(lián)網(wǎng)的基礎(chǔ),要想理解互聯(lián)網(wǎng),就必須理解這個(gè)模型。TCP/IP是一系列網(wǎng)絡(luò)協(xié)議的總稱,這些協(xié)議的作用是使計(jì)算機(jī)之間可以進(jìn)行信息交換。所謂協(xié)議,可以理解成計(jì)算機(jī)之間交談的語(yǔ)言,每種協(xié)議都有自己的作用。TCP/IP中有很多種協(xié)議,這些協(xié)議可以分為4層,被稱為TCP/IP模型的4層結(jié)構(gòu),如圖所示。第19章Java網(wǎng)絡(luò)編程使用Socket進(jìn)行基于TCP的編程要使用Java進(jìn)行網(wǎng)絡(luò)編程,主要的編程對(duì)象就是傳輸層的TCP和UDP。本節(jié)將介紹如何在Java語(yǔ)言中基于TCP編程。Java語(yǔ)言中,往往使用Socket進(jìn)行TCP編程。Socket通常稱為“套接字”,應(yīng)用程序通常通過(guò)“套接字”向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求,一個(gè)Socket由一個(gè)IP地址和一個(gè)端口號(hào)唯一確定。JavaAPI的包中提供了Socket類和ServerSocket類,分別表示雙向連接中的客戶端和服務(wù)器端,是進(jìn)行Socket編程的主要API。Socket類和ServerSocket類都提供了很多構(gòu)造方法,可以方便地創(chuàng)建對(duì)象。代碼如下:第19章Java網(wǎng)絡(luò)編程使用Datagram進(jìn)行基于UDP的編程數(shù)據(jù)傳輸協(xié)議—UDP。Java中使用數(shù)據(jù)報(bào)進(jìn)行基于UDP的網(wǎng)絡(luò)編程。數(shù)據(jù)報(bào)如同郵件系統(tǒng),不能保證可靠的傳輸,而面向連接的TCP就好比打電話,雙方能肯定對(duì)方接收到了信息。JavaAPI中,包提供了DatagramSocket和DatagramPacket兩個(gè)類,用來(lái)支持?jǐn)?shù)據(jù)報(bào)通信,DatagramSocket用來(lái)在程序之間建立傳送數(shù)據(jù)報(bào)的通信連接,DatagramPacket用來(lái)表示一個(gè)數(shù)據(jù)報(bào)。用數(shù)據(jù)報(bào)方式進(jìn)行網(wǎng)絡(luò)編程時(shí),無(wú)論是客戶端還是服務(wù)器端都要建立一個(gè)DatagramSocket對(duì)象,用來(lái)接收或發(fā)送數(shù)據(jù)報(bào),然后使用DatagramPacket對(duì)象作為傳輸數(shù)據(jù)的載體。構(gòu)造方法中的常用參數(shù)buf是一個(gè)數(shù)組,用來(lái)存放數(shù)據(jù)報(bào)數(shù)據(jù);length表示數(shù)據(jù)報(bào)中數(shù)據(jù)的長(zhǎng)度;addr和port表示目的地址和端口;offset表示數(shù)據(jù)報(bào)的位移量。第19章Java網(wǎng)絡(luò)編程日期日期是在實(shí)際應(yīng)用開(kāi)發(fā)中經(jīng)常使用的類型,而Java中的日期是比較復(fù)雜的一部分內(nèi)容。API中與日期有關(guān)的類主要有Date、Calendar、GregorianCalendar、DateFormat及SimpleDateFormat。1.java.util.Date類Date類用來(lái)表示特定的瞬間,能夠精確到毫秒。2.java.util.Calendar類Calendar類是一個(gè)抽象類,是系統(tǒng)時(shí)間的抽象表示。由于日歷與當(dāng)前平臺(tái)的時(shí)區(qū)等信息有關(guān),所以Calendar類是一個(gè)平臺(tái)相關(guān)類,類中提供的靜態(tài)getInstance方法可以返回當(dāng)前平臺(tái)下的Calendar實(shí)例。Calendar類中定義了大量靜態(tài)常量,表示日歷中的年、月、日等信息,如YEAR、MONTH等。值得注意的是,MONTH從0開(kāi)始編號(hào)。Calendar類中定義了get(int)方法,可以將時(shí)間中的年、月、日等信息返回。3.java.util.GregorianCalendar類GregorianCalendar類是Calendar類的一個(gè)實(shí)現(xiàn)類,提供了目前大多數(shù)國(guó)家使用的標(biāo)準(zhǔn)日歷系統(tǒng),可以結(jié)合Calendar抽象類使用。GregorianCalendar類是一個(gè)具體類,所以可以使用類的任意構(gòu)造方法進(jìn)行實(shí)例化。4.java.text.DateFormat類通過(guò)上面的實(shí)例可見(jiàn),為了能夠?qū)⑷掌诎凑找欢ǜ袷捷敵?,總要進(jìn)行比較復(fù)雜的轉(zhuǎn)換。DateFormat類用來(lái)對(duì)日期和時(shí)間類型進(jìn)行轉(zhuǎn)換,是一個(gè)抽象類,定義了日期和時(shí)間格式化的通用方法format,以與語(yǔ)言無(wú)關(guān)的方式格式化并分析日期和時(shí)間。DateFormat類提供了很多靜態(tài)方法,可以獲得基于默認(rèn)或給定語(yǔ)言環(huán)境和多種格式化風(fēng)格的格式化對(duì)象。格式化風(fēng)格包括FULL、LONG、MEDIUM和SHORT4種。5.java.text.SimpleDateFormat類SimpleDateFormat類是DateFormat類的子類,可以使用任何用戶自定義的日期格式模式進(jìn)行格式化。用戶自定義的模式用一個(gè)字符串表示。第20章其他常用API國(guó)際化很多應(yīng)用往往需要在不同語(yǔ)言環(huán)境及區(qū)域使用,也就是說(shuō),不同語(yǔ)言環(huán)境及區(qū)域的用戶訪問(wèn)應(yīng)用時(shí),應(yīng)用程序必須使用用戶能看懂的語(yǔ)言和符合用
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 供暖承包合同
- 裝修總承包合同
- 標(biāo)識(shí)標(biāo)牌制作合同
- 數(shù)據(jù)存儲(chǔ)與分析服務(wù)合同
- 英文服務(wù)合同范本
- 精技術(shù)合作開(kāi)發(fā)合同
- 合同主體變更協(xié)議
- 房屋買賣居間合同簽訂注意事項(xiàng)
- 關(guān)于固定期限聘用合同
- 公對(duì)公的借款合同正規(guī)范本
- 員工內(nèi)部眾籌方案
- 復(fù)變函數(shù)與積分變換期末考試試卷及答案
- 初中班級(jí)成績(jī)分析課件
- 勞務(wù)合同樣本下載
- 聰明格練習(xí)題(初、中級(jí))
- 血液透析水處理系統(tǒng)演示
- 小批量試制總結(jié)報(bào)告
- 2023年經(jīng)濟(jì)開(kāi)發(fā)區(qū)工作會(huì)議表態(tài)發(fā)言
- YY/T 0216-1995制藥機(jī)械產(chǎn)品型號(hào)編制方法
- 糖尿病足與周圍血管病01課件
- 2022年試行林木采伐管理方案
評(píng)論
0/150
提交評(píng)論