【ch09】集合、反射與泛型_第1頁
【ch09】集合、反射與泛型_第2頁
【ch09】集合、反射與泛型_第3頁
【ch09】集合、反射與泛型_第4頁
【ch09】集合、反射與泛型_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

集合、反射與泛型Java程序設計第九章01集合9.1集合集合集合可理解為一個容器,容器可以包含有多個元素,這些元素通常是一些Java對象。Java的集合類主要由兩個接口派生而出:Collection和Map,這兩個接口又包含一些子接口或實現類。常見的集合容器主要有映射(Map)、集合(Set)、列表(List)、散列表(Hashtable)等抽象數據結構。每種集合容器的抽象數據結構定義的一些標準編程接口稱為集合框架。集合框架主要由一組精心設計的接口、類和隱含在其中的算法組成,通過它們可以采用集合的方式完成Java對象的存儲、獲取、操作及轉換等功能。9.1集合9.1.1List接口List接口繼承自Collection接口,但在Collection接口的基礎上加上了一個集合元素順序的限定,也就是說,List中每個元素都有特定的位置(索引),所以也稱為有序集合(OrderedCollection)或列表、序列等。因此,List不但可以使用Collection接口中的全部方法,而且增加了一些根據索引來操作集合元素的方法,如表9-1所示。9.1集合1.ArrayListArrayList可以視為實現了List接口的可變數組。ArrayList類的主要方法如表9-2所示。除上述主要方法外,排序是ArrayList類最常見的應用。9.1集合2.LinkedListLinkedList與ArrayList一樣,實現了List接口,只是ArrayList是List接口的大小可變數組的實現,LinkedList是List接口的鏈表實現?;阪湵韺崿F的方式使LinkedList在插入和刪除時更優(yōu)于ArrayList,而隨機訪問時則比ArrayList遜色些。LinkedList能實現所有可選的列表操作,并允許所有的元素(包括null)。除實現List接口之外,LinkedList類還為列表的開頭及結尾處的get、remove和insert元素提供了統一的命名方法。這些操作允許將鏈表作為堆棧、隊列或雙端隊列。LinkedList類的主要方法如表9-3所示。9.1集合9.1.2Set接口Set接口也是Collection接口的子接口,但是與Collection和List接口不同的是,Set接口中不能加入重復的元素。Set接口的定義如下:publicinterfaceSet<E>extendsCollection<E>從定義上看,Set接口與List接口的定義并沒有太大區(qū)別。但是Set接口的主要方法與Collection是一致的,也就是說,Set接口并沒有對Collection接口進行擴充,只是比Collection接口的要求更嚴格,不能增加重復元素。Set接口的實例無法像List接口那樣可以進行雙向輸出,因為此接口沒有提供List接口中定義的get(intindex)方法。Set接口的實現類主要有:HashSet、TreeSet、LinkedHashSet等。這些實現類的共同點就是每個相同的項只能保存一份。9.1集合1.HashSetHashSet采用復雜的散列存儲方式存儲元素,所以元素沒有順序。使用HashSet能夠最快地獲取集合中的元素,效率非常高(以空間換時間)。HashSet可根據hashCode和equals的值判斷兩個對象是否是同一個對象,如果hashCode相等,并且equals返回true,則這兩個對象是同一個對象。9.1集合【例9-4】學生類Student在保存學生姓名時將姓和名分別保存在last和first成員變量中,輸入一個班級所有學生的姓和名,最終輸出該班級學生的不同姓氏(相同姓氏不能重復輸出)。【程序】【運行結果】【程序說明】從程序的運行結果中可以清楚地看出,重復元素只會增加一次,而且程序運行時向集合中加入元素的順序并不是集合中的元素保存順序,證明HashSet類中的元素是無序排列的。9.1集合2.TreeSet如果要對輸入的數據進行有序排列,則要使用TreeSet類。TreeSet類的定義如下:publicclassTreeSetextendsAbstractSetimplementsSortedSet,Cloneable,Serializable其中,TreeSet類繼承了AbstractSet類,此類的定義如下: publicabstractclassAbstractSet extendsAbstractCollection implementsSet9.1集合9.1.3Map接口Map接口也稱為字典或關聯數組,用于保存具有映射關系的數據(key-vlaue)。Map中的key不允許重復,即同一個Map對象的任何兩個key通過equals方法比較總是返回false。Map中包含keySet()方法,用于返回Map中所有key組成的Set集合。Map集合與Set集合元素的存儲形式很像,如Set接口下有HashSet、LinkedHashSet、SortedSet(接口)、TreeSet、EnumSet等實現類和子接口,而Map接口下則有HashMap、LinkedHashMap、SortedMap(接口)、TreeMap、EnumMap等實現類和子接口。Map中的value非常類似于List,元素與元素之間可以重復,每個元素可以根據索引(key)來查找。9.1集合Map接口中定義的主要方法如下:(1)voidclear():刪除Map對象中所有的key-value對。(2)booleancontainsKey(Objectkey):查詢Map中是否包含指定的key,如果包含,則返回true。(3)booleancontainsValue(Objectvalue):查詢Map中是否包含一個或多個value,如果包含,則返回true。(4)SetentrySet():返回Map中所有包含的key-value對組成的Set集合,每個集合元素都是Map.Entry(Entry是Map的內部類)對象。(5)Objectget(Obejctkey):返回指定的key所對應的value;如果此Map中不包含key,則返回null。9.1集合(6)booleanisEmpty():查詢該Map是否為空(即不包含任何key-value對),如果為空,則返回true。(7)SetkeySet():返回該Map中所有key組成的Set集合。(8)Objectput(Objectkey,Objectvalue):添加一個key-value對,如果當前Map中已有一個與該key相等的key-value對,則新的key-value對會覆蓋原來的key-value對。(9)Objectremove(Objectkey):刪除指定的key對應的key-value對,返回被刪除的key所關聯的value,如果該key不存在,返回null。(10)intsize():返回該Map中key-value對的個數。(11)Collectionvalues():返回該Map中所有value組成的Collection。9.1集合Map接口包括一個內部類:Entry。該類封裝了一個key-value對,Entry類包含3個方法:(1)Objectgetkey():返回該Entry中包含的key值。(2)ObjectgetValue():返回該Entry中包含的value值。(3)ObjectsetValue():設置該Entry中包含的value值,并返回新設置的value值。因此,也可以把Map理解成一個特殊的Set,只是該Set中包含的集合元素是Entry對象,而不是普通對象。9.1集合1.HashMapHashMap是基于哈希表的Map接口的非同步實現。此實現提供所有可選的映射操作,并允許使用null值和null鍵。HashMap不保證映射的順序,特別是它不保證順序恒久不變。HashMap提供了3個構造函數:(1)HashMap():構造一個具有默認初始容量(16)和默認加載因子(0.75)的空HashMap。(2)HashMap(intinitialCapacity):構造一個帶指定初始容量和默認加載因子(0.75)的空HashMap。(3)HashMap(intinitialCapacity,floatloadFactor):構造一個帶指定初始容量和加載因子的空HashMap。9.1集合HashMap類的主要方法如下:(1)voidclear():從此映射中移除所有映射關系。(2)Objectclone():返回此HashMap的淺表副本:并不復制鍵和值本身。(3)booleancontainsKey(Objectkey):如果此映射包含對于指定鍵的映射關系,則返回true。(4)booleancontainsValue(Objectvalue):如果此映射將一個或多個鍵映射到指定值,則返回true。(5)Set<Map.Entry<K,V>>entrySet():返回此映射所包含的映射關系的Set視圖。(6)Vget(Objectkey):返回指定鍵所映射的值;如果對于該鍵來說此映射不包含任何映射關系,則返回null。9.1集合(7)booleanisEmpty():如果此映射不包含鍵值映射關系,則返回true。(8)Set<K>keySet():返回此映射中所包含的鍵的Set視圖。(9)Vput(Kkey,Vvalue):在此映射中關聯指定值與指定鍵。(10)voidputAll(Map<?extendsK,?extendsV>m):將指定映射的所有映射關系復制到此映射中,這些映射關系將替換此映射目前針對指定映射中所有鍵的所有映射關系。(11)Vremove(Objectkey):從此映射中移除指定鍵的映射關系(如果存在)。(12)intsize():返回此映射中的鍵值映射關系數。(13)Collection<V>values():返回此映射所包含的值的Collection視圖。9.1集合【例9-6】輸入字符串,統計該字符串中出現的字符及其出現的次數?!境绦颉俊具\行結果】輸入內容為:顯示輸出內容為:9.1集合2.TreeMapMap接口派生了一個SortedMap子接口,TreeMap為其實現類。類似TreeSet排序,TreeMap也是基于紅黑樹對TreeMap中所有key進行排序的,從而保證TreeMap中所有key-value對處于有序狀態(tài)。TreeMap中判斷兩個key是否相等,也是通過equals比較(返回true,則相等)也可通過compareTo()方法(返回0,則相等)。9.1集合TreeMap中提供了很多根據key的順序來訪問Map中的key-value對的方法:(1)Map.EntryfirstEntry():返回該Map中最小key值所對應的key-value對,如果該Map為空,則返回null。(2)ObjectfirstKey():返回該Map中的最小key值,如果該Map為空,則返回null。(3)Map.EntrylastEntry():返回該Map中最大key值所對應的key-value對,如果該Map為空或不存在這樣的key-value,則返回null。(4)ObjectlastKey():返回該Map中的最大key值,如果該Map為空或不存在這樣的key,則返回null。(5)Map.EntryhigherEntry(Objectkey):返回該Map中位于key后一位的key-value對(即大于指定key值的最小key值所對應的key-value對)。如果該Map為空,則返回null。9.1集合(6)ObjecthigherKey():返回該Map中位于key后一位的key值(即大于指定key的最小key值)。如果該Map為空或不存在這樣的key,則返回null。(7)Map.EntrylowerEntry(Objectkey):返回該Map中位于key前一位的key-value對(即小于指定key的最大key所對應的key-value對)。如果該Map為空或不存在這樣的key-value對,則返回null。(8)ObjectlowerKey():返回該Map中位于key前一位的key值(即小于指定key的最大key值)。如果該Map為空或不存在這樣的key值,則返回null。(9)NavigableMapsubMap(ObjectfromKey,booleanfromInclusive,Objecttokey,booleantolnclusive):返回該Map的子Map,key的范圍是從fromKey(是否包括取決于第2個參數)到tokey(是否包括取決于第4個參數)。9.1集合(10)SorterMapsubMap(ObjectfromKey,ObjecttoKey):返回該Map的子Map,key的范圍是從fromKey(包括)到toKey(不包括)。(11)SortedMaptailMap(ObjectfromKey,booleaninclusive):返回該Map的子Map,key的范圍是大于fromkey(是否包括取決于第二個參數)。(12)NavigableMapheadMap(ObjecttoKey,booleanlnclusive):返回該Map的子Map,key的范圍是小于fromKey(是否包括取決于第二個參數)。9.1集合【例9-7】對隨機輸入的華東六省市名稱及其介紹按照省份名稱的漢語拼音排序,并輸出每個省份的介紹?!境绦颉俊具\行結果】【程序說明】程序中,Collator類用來簡化處理各種語言之間的差別性,主要處理規(guī)范化的典型等效字符和多層次的比較。9.1集合9.1.4Collection接口一個Collection表示一組元素對象。Collection接口是除Map子體系之外所有集合對象都必須實現的接口,也就是說,Collection接口是整個Collection子體系的根接口。一些Collection接口的實現允許重復元素,而另外一些則不允許。Java平臺沒有提供任何對這個接口的直接實現,但是提供了一些更加專用的子接口;其中,兩個常用的子接口是List和Set,分別表示有序可重復、無序不可重復的集合。9.1集合【例9-8】隨機輸入n名學生的姓名,以輸入空字符串為結束,數據保存在ArrayList集合中,編程實現該集合的for-each循環(huán)遍歷輸出和迭代器訪問遍歷輸出,然后在迭代器遍歷中刪除所有字數大于2的姓名,最終輸出集合結果?!境绦颉俊具\行結果】輸入內容為:顯示輸出內容為:【程序說明】上述代碼中,如果把iterator2.remove()放到iterator2.next()之前,就會拋出java.lang.IllegalStateException異常。02反射9.2反射9.2.1類反射Reflection是Java程序開發(fā)語言的特征之一,它允許運行中的Java程序對自身進行檢查,或者說“自審”,并能直接操作程序的內部屬性。反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過采用某種機制來實現對自己行為的描述(self-representation)和監(jiān)測(examination),并能根據自身行為的狀態(tài)和結果,調整或修改應用所描述的行為的狀態(tài)和相關的語義。Java中,反射是一種強大的能力,它使開發(fā)人員能夠創(chuàng)建靈活的代碼,這些代碼可以在運行時裝配,無須在組件之間進行源代碼鏈接。9.2反射【例9-9】實現類的成員方法的查詢程序,輸入一個類的完整名稱,輸出該類的所有成員方法?!境绦颉俊具\行結果】輸入內容為:顯示輸出內容為:【程序說明】該程序使用Class.forName載入指定的類,然后調用getDeclaredMethods來獲取這個類中定義的方法列表。java.lang.reflect.Methods是用來描述某個類中單個方法的類。9.2反射調用都遵循一種標準格式,以下是用于查找構造函數的一組反射調用:(1)ConstructorgetConstructor(Class[]params):獲得使用特殊參數類型的公共構造函數。(2)Constructor[]getConstructors():獲得類的所有公共構造函數。(3)ConstructorgetDeclaredConstructor(Class[]params):獲得使用特定參數類型的構造函數(與接入級別無關)。(4)Constructor[]getDeclaredConstructors():獲得類的所有構造函數(與接入級別無關)。9.2反射獲取成員變量的類的反射調用不同于那些用于獲取構造函數的調用,在參數類型數組中使用了字段名,例如:(1)FieldgetField(Stringname):獲得名稱為name的公共成員變量。(2)Field[]getFields():獲得類的所有公共成員變量。(3)FieldgetDeclaredField(Stringname):獲得類聲明的名稱為name的成員變量。(4)Field[]getDeclaredFields():獲得類聲明的所有成員變量。9.2反射用于獲得成員方法的函數有:(5)MethodgetMethod(Stringname,Class[]params):使用特定的參數類型,獲得名稱為name的公共方法。(6)Method[]getMethods():獲得類的所有公共方法。(7)MethodgetDeclaredMethod(Stringname,Class[]params):使用特定的參數類型,獲得類聲明的名稱為name的方法。(8)Method[]getDeclaredMethods():獲得類聲明的所有方法。9.2反射使用反射的時候一般遵循3個步驟:(1)獲得想操作的類的java.lang.Class對象。常見的方式為:①Classc=Class.forName("java.lang.String"):得到一個String類的對象。②Classc=int.class:得到基本類型整型(int類型)。③Classc=Integer.TYPE:這條語句得到基本類型整型的封裝類Integer定義的TYPE字段。(2)調用上述的getDeclaredMethods()等方法,獲得該類中定義的所有的(或相關的)成員方法;或調用上述的getDeclaredFields()等方法,獲得該類中定義的所有的(或相關的)成員變量。(3)使用reflectionAPI進一步獲取相關信息。9.2反射9.2.2標注反射是很多技術的基礎,標注(Annotation)就是建立在反射基礎上的一種重要的技術,它可以對類型、方法、屬性、字段、方法參數等信息進行修飾??梢允褂谩癅+Annotation名”的方式來使用Annotation。Annotation在多種Java技術中得到廣泛應用,其中@Override是最常見的標注之一。標注對于其所標注代碼部分(類型、方法、屬性、字段、方法參數等)的語義不產生影響,但是卻能夠將其所標注的代碼部分的相關信息返回給編譯器或外部程序,并由編譯器或外部程序進行處理。這個功能在代碼檢查、代碼自動生成、文檔自動生成、運行時動態(tài)處理等方面十分有用。03泛型9.3泛型泛型(GenericType或Generics)是對Java語言類型系統的一種擴展,以支持創(chuàng)建可以按類型進行參數化的類??梢园杨愋蛥狄暈槭褂脜祷愋蜁r指定的類型的一個占位符,就像方法的形式參數是運行時傳遞的值的占位符一樣??梢栽诩峡蚣埽–ollectionFramework)中看到泛型的動機。例如,Map類允許向一個Map中添加任意類的對象,最常見的情況是在給定的映射(Map)中保存某個特定類型(比如String)的對象。理想情況下,可能會得出這樣一個觀點,即m是一個Map,它將String鍵映射到String值。這可以消除代碼中的強制類型轉換,同時獲得一個附加的類型檢查層,該檢查層可以防止有人將錯誤類型的鍵或值保存在集合中,這就是泛型所做的工作。9.3泛型(1)類型安全。泛型的主要目標是提高Java程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在一個高得多的程度上驗證類型假設。沒有泛型,這些假設就只存在于程序員的頭腦中(幸運的話,還存在于代碼注釋中)。(2)消除強制類型轉換。泛型的另一個優(yōu)點是消除源代碼中許多的強制類型轉換,增強代碼的可讀性,并且減少出錯概率。(3)潛在的性能收益。泛型為較大的優(yōu)化帶來可能,在泛型的初始實現中,編譯器使用強制類型轉換(沒有泛型的話,程序設計者會指定這些強制類型轉換)插入生成的字節(jié)碼中,但是使多類型信息可用于編譯器這一事實,為未來版本的JVM的優(yōu)化帶來可能。9.3泛型對于常見的泛型模式,推薦的名稱如下:(1)K:鍵,如映射的鍵。(2)V:值,如List和Set的內容,或者Map中的值。(3)E:異常類。(4)T:泛型。關于泛型,一個常見的誤區(qū)就是假設它們像數組一樣是協變的,其實它們不是協變的,例如,List<Object>不是List<String>的父類型。9.3泛型泛型類在多個方法參數間實施類型約束。在List<V>中,類型參數V出現在get()、add()、contains()等方法的參數中。當創(chuàng)建一個Map<K,V>類型的變量時,就在方法之間聲明一個類型約束,傳遞給add()的值與get()的返回值的類型相同。類似地,聲明泛型方法是因為想要在該方法的多個參數之間聲明一個類型約束。在以下兩種情況下,我們選擇使用泛型方法,而不是將類型T添加到類定義:(1)當泛型方法是靜態(tài)方法時,不能使用類型參數。(2)若T上的類型約束對于方法而言是局部的,則意味著沒有在相同類的另一個方法中使用相同類型T的約束。9.3泛型【程序】定義一個泛型類,可以

溫馨提示

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

評論

0/150

提交評論