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

下載本文檔

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

文檔簡介

1、第8章 Java泛型與集合類核心內(nèi)容:1. 集合的作用與概念2. 泛型的作用與用法。3. Set、List、Map的用法4. Iterator、Enumeration的用法8.1 早期的集合類集合可理解為一個(gè)容器,該容器主要指映射(map)、集合(set)、列表(list)、散列表(hashtable)等抽象數(shù)據(jù)結(jié)構(gòu)。容器可以包含有多個(gè)元素,這些元素通常是一些Java對象。針對上述抽象數(shù)據(jù)結(jié)構(gòu)所定義的一些標(biāo)準(zhǔn)編程接口稱之為集合框架。集合框架主要是由一組精心設(shè)計(jì)的接口、類和隱含在其中的算法所組成,通過它們可以采用集合的方式完成Java對象的存儲、獲取、操作以及轉(zhuǎn)換等功能。集合框架的設(shè)計(jì)是嚴(yán)格按照

2、面向?qū)ο蟮乃枷脒M(jìn)行設(shè)計(jì)的,它對上述所提及的抽象數(shù)據(jù)結(jié)構(gòu)和算法進(jìn)行了封裝。封裝的好處是提供一個(gè)易用的、標(biāo)準(zhǔn)的編程接口,使得在實(shí)際編程中不需要再定義類似的數(shù)據(jù)結(jié)構(gòu),直接引用集合框架中的接口即可,提高了編程的效率和質(zhì)量。此外還可以在集合框架的基礎(chǔ)上完成如堆棧、隊(duì)列和多線程安全訪問等操作。在集合框架中有幾個(gè)基本的集合接口,分別是Collection接口、List接口、Set接口和Map接口,它們所構(gòu)成的層次關(guān)系如圖8-1所示。Collection接口Set接口List 接口Map接口 圖8-1 集合框架層次關(guān)系圖(1)Collection接口是一組允許重復(fù)的對象。(2)Set接口繼承Collectio

3、n,但不允許集合中出現(xiàn)重復(fù)元素。(3)List接口繼承Collection,允許集合中有重復(fù),并引入位置索引。(4)Map接口與Collection接口無任何關(guān)系,Map的典型應(yīng)用是訪問按關(guān)鍵字存儲的值,所包含的是鍵值對,而不是單個(gè)獨(dú)立的元素。作為對上述接口的實(shí)現(xiàn),Java語言目前主要提供下述類的定義,如表8-1所示 表8-1 集合接口及其類的實(shí)現(xiàn)接口集合類的實(shí)現(xiàn)歷史集合類SetHashSetTreeSetListArrayList VectorLinkedList StackMapHashMap HashtableTreeMap由于在JDK1.5當(dāng)中增加了泛型,我們把JDK1.5之前不支持泛

4、型的集合類稱之為早期集合類。早期的集合有個(gè)缺點(diǎn):當(dāng)我們把一個(gè)對象存放到集合里后,集合就會“忘記”這個(gè)對象的數(shù)據(jù)類型,當(dāng)再次取出該對象時(shí),該對象的編譯類型就變成了Object類型。早期的集合之所以被設(shè)計(jì)成這樣,是因?yàn)樵O(shè)計(jì)集合的程序員不知道我們需要用它來保存什么類型的對象。所以他們把集合設(shè)計(jì)成能保存任何類型的對象。但這樣做也帶來了兩個(gè)問題:一、集合對元素類型沒有任何限制,例如只想創(chuàng)建一個(gè)保存String類型的集合,但是程序也允許把boolean類型的對象存放在該集合當(dāng)中,這樣容易引發(fā)異常。二、由于把對象保存在集合當(dāng)中時(shí),集合忘記了對象的數(shù)據(jù)類型,只知道它存放的是Object類型,因此取出集合元素后

5、通常要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。這種強(qiáng)制類型轉(zhuǎn)換既會增加程序的復(fù)雜度,也可能引發(fā)ClassCastException。【例8-1】 Test.java 早期集合類1 import java.util.ArrayList;2 import java.util.Iterator;3 import java.util.List;4 public class Test 5 public static void main(String args) 6 List list=new ArrayList();7 list.add(beijing);8 list.add(wuhan);9 list.add(shangh

6、ai);10 /list.add(4);11 for(int i=0;ijava Test beijing wuhan shanghai程序說明:上述程序的第6行是創(chuàng)建一個(gè)List集合對象,第7、8、9行是向該集合當(dāng)中添了一個(gè)3個(gè)String類型的對象元素,第11、12、13、14行是通過for循環(huán)將集合當(dāng)中的元素取出,轉(zhuǎn)換為String類型并輸出。上述程序只是創(chuàng)建了一個(gè)List對象,而且只用List對象來保存字符串對象。但是對于保存在List對象當(dāng)中的數(shù)據(jù)類型我們不能做任何的限制。如果在程序的第10行,我們不小心把一個(gè)int類型的數(shù)據(jù)保存到List當(dāng)中,就將導(dǎo)致程序在第12行出現(xiàn)ClassC

7、astException異常。自JDK1.5以后,Java引入了泛型的概念,允許我們在創(chuàng)建集合時(shí)指定集合元素的類型。這樣添加數(shù)據(jù)元素到集合中時(shí)會做類型檢查。如果要添加的數(shù)據(jù)元素與指定的數(shù)據(jù)類型不匹配,編譯時(shí)會報(bào)錯。8.2 泛型在面向?qū)ο缶幊陶Z言中,多態(tài)算是一種泛化機(jī)制。例如,你可以將方法的參數(shù)類型設(shè)為基類,那么該方法就可以接受從這個(gè)基類中導(dǎo)出的任何類作為參數(shù)。這樣的方法更加通用一些,可應(yīng)用的地方也多一些。但有時(shí)候,拘泥于類的單繼承體系,也會使程序受限太多。如果方法的參數(shù)是一個(gè)接口,而不是一個(gè)類,這種限制就放松了許多。因?yàn)槿魏螌?shí)現(xiàn)了該接口的類都能夠滿足該方法。可是有時(shí)候,即便使用了接口,對程序的

8、約束也還是太強(qiáng)了。因?yàn)橐坏┲该髁私涌冢鸵竽愕拇a必須使用特定的接口。而我們希望達(dá)到的目的是編寫更通用的代碼,要使代碼能夠應(yīng)用于“某種不具體的類型”,而不是一個(gè)具體的接口或類。在Java SE 5中增加了泛型機(jī)制。“泛型”這個(gè)術(shù)語的意思是:“適用于許多的類型”。泛型實(shí)現(xiàn)了參數(shù)化類型的概念,使代碼可以應(yīng)用于多種類型。8.2.1 泛型類 一個(gè)泛型類就是具有一個(gè)或多個(gè)類型變量的類。本節(jié)使用一個(gè)簡單的Pair類作為例子。public class Pair private T first;private T second;public Pair()first=null; second=null;pub

9、lic Pair(T first,T second)this.first=first; this.second=second;public T getFirst()return first;public T getSecond()return second;public void setFirst(T newValue)first=newValue;public void setSecond(T newValue)second=newValue; Pair類引入了一個(gè)類型變量T,用尖括號括起來,并放在類名的后面。泛型類可以有多個(gè)類型變量。例如,可以定義Pair類,其中第一個(gè)成員變量和第二個(gè)成員

10、變量使用不同的類型:public class Pair.類定義中的類型變量指定方法的返回類型以及成員變量和局部變量的類型。例如:private T first;用具體的類型替換類型變量就可以實(shí)例化泛型類型,例如:Pair可以將結(jié)果想像成帶有構(gòu)造器的普通類:public class Pair private String first;private String second;public Pair()first=null; second=null;public Pair(String first,String second)this.first=first; this.second=secon

11、d;public String getFirst()return first;public String getSecond()return second;public void setFirst(String newValue)first=newValue;public void setSecond(String newValue)second=newValue;【例8-2】 PairTest.java 泛型類1 public class PairTest2 public static void main(String args)3 Pair pair=new Pair(Hello,Java

12、);4System.out.println(first=+pair.getFirst();5System.out.println(second=+pair.getSecond();67輸出結(jié)果:D:JAVA8java PairTestfirst=Hellosecond=Java程序分析: 上述程序的第3行創(chuàng)建了一個(gè)泛型類對象pair,并指定該對象的成員變量的類型為String類型。并調(diào)用其帶String類型參數(shù)的構(gòu)造方法對其進(jìn)行初始化。將pair對象的第一個(gè)成員變量first的值設(shè)置為Hello,第二個(gè)成員變量second的值設(shè)置為Java。第4,5行分別調(diào)用pair對象的getFirst()

13、、getSecond()方法獲得成員變量first、second的值并輸出到控制臺。8.2.2 泛型方法前面已經(jīng)介紹了如何定義一個(gè)泛型類。實(shí)際上,還可以定義一個(gè)帶有參數(shù)類型的方法即泛型方法。泛型方法使得該方法能夠獨(dú)立于類而產(chǎn)生變化,泛型方法所在的類可以是泛型類,也可以不是泛型類。創(chuàng)建一個(gè)泛型方法常用的形式如下: 訪問修飾符 static final 返回值 方法名( 形式參數(shù)列表 )下面我們在GenericMethod類當(dāng)中聲明一個(gè)f ( )泛型方法,用于返回調(diào)用該方法時(shí),所傳入的參數(shù)類型的類名。【例8-3】 GnericMethodTest.java 泛型方法1class GenericMe

14、thod2 public void f(T x)3 System.out.println(x.getClass().getName();4567 public class GenericMethodTest8 public static void main(String args)9 GenericMethod gm=new GenericMethod();10 gm.f( );11 gm.f(1);12 gm.f(1.0f);13 gm.f(c);14 gm.f(gm);1516輸出結(jié)果:D:JAVA8java GenericMethodTestGenericMethod程序分析: 上述程序

15、的第9行創(chuàng)建了一個(gè)GenericMethod類型的對象gm。第10行調(diào)用該對象的f()方法,并傳遞參數(shù)為。f()方法通過getClass()方法獲取傳入?yún)?shù)的類別,并通過getName()方法獲取該類別的名字,然后輸出到控制臺。同理,第1114行分別將1、1.0f、c、gm所屬類別的名字輸出到標(biāo)準(zhǔn)控制臺。 注意:當(dāng)使用泛型類時(shí),必須在創(chuàng)建對象的時(shí)候指定類型參數(shù)的值,而使用泛型方法的時(shí)候,通常不必指明參數(shù)類型,因?yàn)榫幾g器會為我們找出具體的類型。這稱為類型參數(shù)推斷。因此我們可以像調(diào)用普通方法一樣調(diào)用f(),編譯器會根據(jù)調(diào)用f()時(shí)傳入的參數(shù)類型與泛型類型進(jìn)行匹配。8.2.3 泛型接口除了泛型類和泛

16、型方法,還可以使用泛型接口。泛型接口的定義與泛型類非常相似,它的聲明形式如下:interface 接口名下面我們創(chuàng)建了一個(gè)名為MinMax的接口,用來返回某個(gè)對象集的最小值或最大值interface MinMaxT extends ComparableT min();T max();MinMax接口類型參數(shù)T是有界類型,它必須是Comparable的子類。注意到Comparable本身也是一個(gè)泛型類,它是由系統(tǒng)定義在類庫中的,可以用來比較兩個(gè)對象的大小。接下來我們定義一個(gè)類MyClass來實(shí)現(xiàn)這個(gè)接口class MyClassT extends Comparable implements Mi

17、nMaxT vals; MyClass(T ob) vals = ob; public T min() T val = vals0; for(int i=1; ivals.length; +i) if (pareTo(val) 0) val = valsi; return val;public T max() T val = vals0; for(int i=1; i 0) val = valsi; return val;注意MyClass的聲明部分:它的類型參數(shù)T必須和要實(shí)現(xiàn)的接口中的聲明完全一樣.反而是接口MinMax的類型參數(shù)T最初是寫成有界形式的,現(xiàn)在已經(jīng)不再需要重寫

18、一遍。下面通過一個(gè)例子來測試MyClass的運(yùn)行情況【例8-4】 MyClassTest.java 泛型接口1 public class MyClassTest2 public static void main(String args)3 Integer inums = 56,47,23,45,85,12,55;4 Character chs = x,w,z,y,b,o,p;5MyClass iob = new MyClass(inums);6MyClass cob = new MyClass(chs);7System.out.println(Max value in inums: +iob.

19、max();8System.out.println(Min value in inums: +iob.min();9System.out.println(Max value in chs: +cob.max();10 System.out.println(Min value in chs: +cob.min();11 12輸出結(jié)果:D:JAVA8java MyClassTestMax value in inums: 85Min value in inums: 12Max value in chs: zMin value in chs: b 程序分析: 上述程序的第3行定義了一個(gè)Integer類

20、型的數(shù)組inums。第4行定義了一個(gè)character類型的數(shù)組chs。第5行創(chuàng)建了一個(gè)MyClass類型的對象iob并指定其參數(shù)類型為Integer類型。即iob對象的成員變量T val為數(shù)組inums。第6行創(chuàng)建了一個(gè)MyClass類型的對象cob.并指定其參數(shù)類型為String類型。即cob對象的成員變量T val為數(shù)組chs。8.2.4 通配類型參數(shù)前面介紹的泛型已經(jīng)可以解決大多數(shù)的實(shí)際問題,但在某些特殊情況下,仍然會有一些問題無法輕松地解決。以Stats類為例,假設(shè)在其中存在一個(gè)名為doSomething()的方法,這個(gè)方法有一個(gè)形式參數(shù),也是Stats類型,如下所示:class S

21、tatsT nums;Stats (T obj)nums = obj;double average()double sum = 0.0;for (int i=0; inums.length; +i)sum += numsi.doubleValue();return sum / nums.length;void doSomething(Stats ob) System.out.println(ob.getClass().getName();下面我們通過StatsTest類來測試Stats運(yùn)行情況【例8-4】StatsTest.java 通配類型參數(shù)1public class StatsTest2

22、 public static void main(String args)3 Integer inums = 1,2,3,4,5;4 Stats iobj = new Stats(inums);5 Double dnums = 1.1,2.2,3.3,4.4,5.5;6 Stats dobj = new Stats(dnums);7 dobj.doSomething(iobj); /iobj和dobj的類型不相同8 9輸出結(jié)果:D:JAVA8javac StatsTest.javaStatsTest.java:7: 無法將 Stats 中的 doSomething(Stats) 應(yīng)用于 (St

23、ats) dobj.doSomething(iobj); /iobj和dobj的類型不相同程序分析:編譯時(shí)出錯是因?yàn)樵赟tatsTest類中,dobj.doSomething(iobj);這條語句有問題。dobj是Stats類型,iobj是Stats類型,由于實(shí)際類型不同,而聲明時(shí)用的是: void doSomething(Stats ob)它的類型參數(shù)也是T,與聲明對象時(shí)的類型參數(shù)T相同。于是在實(shí)際使用中,就要求iobj和dobj的類型必須相同。 解決這個(gè)問題的辦法是使用Java提供的通配符?,它的使用形式如下: genericClassName 現(xiàn)將上面Stats類當(dāng)中的doSomethi

24、ng()可以聲明成這個(gè)樣子: void doSomething(Stats ob)它表示這個(gè)參數(shù)ob可以是任意的Stats類型,于是調(diào)用該方法的對象就不必和實(shí)際參數(shù)對象類型一致了?,F(xiàn)執(zhí)行StatsTest類,查看通配符的效果,輸出結(jié)果如下:D:JAVA8java StatsTestStats注意由于泛型類Stats的聲明中,T是有上界的:class Stats。故void doSomething(Stats ob) /這里使用了類型通配符其中,通配符?有一個(gè)默認(rèn)的上界,就是Number。如果想改變這個(gè)上界,也是可以的,但改變后的上界必須是Number類的子類。比如Stats ob但是不能寫成這

25、樣: Stats ob因?yàn)镮nteger是Number的子類,而String不是Number的子類。通配符無法將上界改變得超出泛型類聲明時(shí)的上界范圍, 最后讀者需要注意一點(diǎn),通配符是用來聲明一個(gè)泛型類的變量的,而不能創(chuàng)建一個(gè)泛型類。比如下面這種寫法是錯誤的:class Stats8.3 泛型集合類 在JDK1.5中增加了泛型,集合類也開始支持泛型,允許在創(chuàng)建集合對象時(shí)通過泛型來指定該集合存儲的對象類型。我們把JDK1.5及以后版本中支持泛型的集合類稱之為“泛型集合類”,作為對集合接口的實(shí)現(xiàn),Java語言目前主要提供下述集合類的定義,如表9-2所示 表8-2 泛型集合類及對應(yīng)的非泛型集合類接口泛

26、型集合類非泛型集合類SetHashSetHashSetTreeSetTreeSetListArrayListArrayListLinkedListLinkedListMapHashMap HashMapTreeeMapTreeMap8.3.1 集合(Set)集合是指一個(gè)不包含重復(fù)元素的對象集合,是數(shù)學(xué)上“集合”概念的一種抽象。其本身是無序的。集合Set接口定義在java.util包中,所定義的方法主要分為兩類:(1)集合和元素之間的方法;(2)集合之間的方法。下面介紹詳細(xì)的方法描述。1.描述集合和元素之間的關(guān)系的方法(1)public boolean add(Object element) 將

27、一個(gè)元素添加到集合中,如果該元素成功添加到集合中,返回true。(2)public boolean remove(Object obj) 從這個(gè)集合中刪除等于obj的對象。如果有匹配的對象被刪除,返回true。(3)public boolean contains(Object obj) 如果集合中包含了一個(gè)與obj相等的對象,返回true。 (4)public int size( ) 返回當(dāng)前存儲在集合中的元素個(gè)數(shù)。 (5)public boolean isEmpty( ) 如果集合中沒有元素,返回true。 (6)public void clear( ) 從這個(gè)集合中刪除所有的元素。 2.描

28、述集合之間關(guān)系的方法(1)public boolean containsAll(Collection other)如果這個(gè)集合包含other集合中的所有元素,返回true。(2)public boolean addAll(Collection other)將other集合中的所有元素添加到這個(gè)集合。添加成功返回true。(3)public boolean removeAll(Collection other)從這個(gè)集合中刪除other集合中存在的所有元素。刪除成功返回true。 (4)public boolean retainAll(Collection other)從這個(gè)集合中刪除所有與ot

29、her集合中的元素不同的元素。刪除成功返回true。在集合框架中,HashSet類和TreeSet類實(shí)現(xiàn)了Set接口。這兩個(gè)類定義在java.util包中一般情況下,采用HashSet類創(chuàng)建一個(gè)無序的集合對象,采用TreeSet類創(chuàng)建有序的集合對象。需要注意的是,添加到TreeSet中的元素必須是可排序的。【例8-6】HashSetTest.java HashSet類的應(yīng)用1 import java.util.HashSet;2 public class HashSetTest3 public static void main(String args)4 boolean b;5 HashSet

30、 s=new HashSet();6 b=s.add(Hello);7 System.out.println(添加單詞Hello,返回為+b);8 b=s.add(Java);9 System.out.println(添加單詞Java,返回為+b);10 b=s.add(Hello);11 System.out.println(添加單詞Hello,返回為+b);12 b=s.add(world);13 System.out.println(添加單詞world,返回為+b);14 for(String element:s)15 System.out.println(element);16 17

31、輸出結(jié)果:D:JAVA8java HashSetTest添加單詞Hello,返回為true添加單詞Java,返回為true添加單詞Hello,返回為false添加單詞world,返回為trueworldJavaHello程序說明: 在上述程序第5行創(chuàng)建了一個(gè)存放String類型的HashSet 集合對象s。713行分別向其中添加了“Hello、Java、“Hello、world共4個(gè)字符串。由于Set類型的集合不能存放重復(fù)的數(shù)據(jù)。故在第10行中,向集合當(dāng)中第二次存放Hello字符串時(shí)。返回結(jié)果為false。第14行調(diào)用了for(:)循環(huán)來輸出集合當(dāng)中的元素。該循環(huán)可以用來輸出集合當(dāng)中的所有元素

32、。類似于迭代器(Iterator)的作用,但使用時(shí)要比迭代器更簡潔,更方便。由于HashSet集合當(dāng)中的元素是無序的,故使用for(:)循環(huán)輸出集合當(dāng)中的元素時(shí),輸出結(jié)果也是隨機(jī)的。該程序每次運(yùn)行時(shí),結(jié)果或都不一樣?!纠?-7】 TreeSetTest.java TreeSet類的應(yīng)用1 import java.util.TreeSet;2 public class TreeSetTest3 public static void main(String args)4 boolean b;5 TreeSet s=new TreeSet();6 b=s.add(Hello);7 System.ou

33、t.println(添加單詞Hello,返回為+b);8 b=s.add(Java);9 System.out.println(添加單詞Java,返回為+b);10 b=s.add(Hello);11 System.out.println(添加單詞Hello,返回為+b);12 b=s.add(world);13 System.out.println(添加單詞world,返回為+b);14 for(String element:s)15 System.out.println(element);16 17 輸出結(jié)果:D:JAVA8java TreeSetTest添加單詞Hello,返回為true

34、添加單詞Java,返回為true添加單詞Hello,返回為false添加單詞world,返回為trueHelloJavaWorld程序說明: 在上述程序第5行創(chuàng)建了一個(gè)存放String類型的TreeSet 集合對象s。713行分別向其中添加了“Hello、Java、“Hello、world共4個(gè)字符串。由于Set類型的集合不能存放重復(fù)的數(shù)據(jù)。故在第10行中,向集合當(dāng)中第二次存放Hello字符串時(shí)。返回結(jié)果為false。第14行調(diào)用了for(:)循環(huán)來輸出集合當(dāng)中的元素。該循環(huán)可以用來輸出集合當(dāng)中的所有元素。在本例中采用TreeSet集合,實(shí)現(xiàn)了集合元素的有序輸出,但這種實(shí)現(xiàn)是有代價(jià)的,即集合中

35、得元素需要具有可比性。什么是可比性?下面通過例8-8和例8-9說明這個(gè)問題?!纠?-8】HashSetDemo1.java HashSet類的應(yīng)用1import java.util.HashSet;2public class HashSetDemo13 public static void main(String args)4 HashSet s=new HashSet();5 s.add(110);6 s.add(new Integer(110);7 for(Object element:s)8 System.out.println(element);910輸出結(jié)果:D:JAVA8java

36、HashSetDemo1110110程序分析: 上述程序的第4行創(chuàng)建了一個(gè)HashSet對象s。第5行向HashSet對象s中添加了一個(gè)字符串對象110,第6行向HashSet對象s中添加了一個(gè)Integer對象110。第7行通過for(:)循環(huán)將HashSet對象中元素輸出?!纠?-9 】TreeSetDemo1.javaTreeSet類的應(yīng)用1import java.util.TreeSet;2public class TreeSetDemo13 public static void main(String args)4 TreeSet s=new TreeSet()5 s.add(110

37、)6 s.add(new Integer(110);7 for(Object element:s)8 System.out.println(element);9 10輸出結(jié)果:D:JAVA8java TreeSetDemo1Exception: java.lang.String cannot at java.lang.IpareTo(Unknown Source) at java.util.TreeMap.put(Unknown Source) at java.util.TreeSet.add(Unknown Source) at TreeSetDemo1.main(TreeSetDemo1.

38、java:6)程序分析: 本例與例8-8其他的程序語句相同,唯一的區(qū)別在于例8-8中采用的是創(chuàng)建一個(gè)HashSet對象,而本例中采用的是創(chuàng)建一個(gè)TreeSet對象,但運(yùn)行結(jié)果卻并不相同。本例的運(yùn)行結(jié)果出現(xiàn)異常,是因?yàn)樽址畬ο蠛虸nteger對象不具備可比性,所以TreeSet在對它們進(jìn)行排序時(shí)得到不正確的結(jié)果,故拋出異常。在本例中由于構(gòu)建TreeSet對象時(shí)沒有指定其存儲的數(shù)據(jù)類型。故字符串對象和Integer對象這兩種不具備可比性的對象都存放到TreeSet對象當(dāng)中。為了避免這種情況。我們可以在聲明TreeSet對象的時(shí)候指定其存放的數(shù)據(jù)類型。即使用泛型?!纠?-10】TreeSetDem

39、o2.javaTreeSet類的應(yīng)用1import java.util.TreeSet;2public class TreeSetDemo13 public static void main(String args)4 TreeSet s=new TreeSet()5 s.add(110)6 s.add(new Integer(110);7 for(Object element:s)8 System.out.println(element);9 10 輸出結(jié)果: The method add(String) in the type TreeSet is not applicable for t

40、he arguments (Integer) 程序分析: 該程序在編譯時(shí)會報(bào)錯。是因?yàn)榈?行中。存放一個(gè)Integer類型的數(shù)據(jù)到TreeSet集合對象中時(shí),編譯器會作類型檢查。若發(fā)現(xiàn)存放的數(shù)據(jù)類型與指定的數(shù)據(jù)類型不一致,就會報(bào)錯。從而避免集合當(dāng)中的數(shù)據(jù)不具備可比性。8.3.3 列表(List) 列表是指一個(gè)有序的對象集合,也稱為一個(gè)對象序列。通過列表接口,可以利用整數(shù)索引(即元素在列表中得位置)對列表中的每個(gè)元素有準(zhǔn)確的控制,包括訪問特定位置的元素對象和查詢特定的元素。與集合不同之處在于列表中允許出現(xiàn)重復(fù)的元素。在列表接口中,除了在集合中所定義的方法外,還有一系列針對列表中特定位置的方法。列

41、表List接口定義在java.util包中,下面介紹列表接口中針對特定位置的方法。(1)public void add(int index, E element) 在列表的指定位置索引為index處插入指定元素element。(2)public boolean addAll(int index, Collection c)將指定Collection c中的所有元素都插入到列表中的指定位置。(3)public E get(int index)返回列表中指定位置的元素。(4)public int indexOf(Object o) 返回此列表中第一次出現(xiàn)的指定元素的索引;如果列表不包含該元素,則返

42、回 -1。(5)public int lastIndexOf(Object o) 返回此列表中最后出現(xiàn)的指定元素的索引;如果列表不包含此元素,則返回 -1。(6)public E remove(int index) 移除列表中指定位置的元素。(7)public E set(int index, E element) 用指定元素替換列表中指定位置的元素。在集合框架中,實(shí)現(xiàn)了列表接口(List)的是ArrayList類和LinkedList類。這兩個(gè)類定義在java.util包中。ArrayList類是通過數(shù)組方式來實(shí)現(xiàn)的,相當(dāng)于可變長度的數(shù)組。LinkedList類則是通過鏈表結(jié)構(gòu)來實(shí)現(xiàn)。由于這

43、兩個(gè)類的實(shí)現(xiàn)方式不同,使得相關(guān)操作方法的代價(jià)也不同。一般說來,若對一個(gè)列表結(jié)構(gòu)的開始和結(jié)束處有頻繁地添加和刪除操作時(shí),一般選用LinkedList類所實(shí)例化的對象表示該列表?!纠?-11】 ArrayListDemo.java ArrayList類應(yīng)用1import java.util.ArrayList;2public class ArrayListDemo3 public static void main(String args)4 ArrayList list=new ArrayList();5 list.add(collection);6 list.add(list);7 list.a

44、dd(ArrayList);8 list.add(LinkedList);9 for(String s:list);10 System.out.println(s);11 list.set(3,ArrayList);12 int len=list.size();13 for(int n=0;njava ArrayListDemocollectionlistArrayListLinkedListcollectionlistArrayListArrayList程序分析: 上述程序第4行創(chuàng)建了一個(gè)ArrayList類型的對象list,并指定其存儲的對象類型為String類型。第58行分別將colle

45、ction 、list、ArrayList、LinkedList添加到list中,第910行通過for(:)循環(huán)輸出list集合當(dāng)中的所有元素。第12行通過set()方法將list集合當(dāng)中的第4個(gè)元素指定為ArrayList,第12行通過size()方法獲取list當(dāng)中的元素個(gè)數(shù)。第1314行通過for循環(huán)輸出list當(dāng)中的所有元素。通常利用LinkedList對象表示一個(gè)堆棧(stack)或隊(duì)列(queue)。對此LinkedList類中特別定義了一些方法,而這是ArrayList類所不具備的。這些方法用于在列表的開始和結(jié)束處添加和刪除元素,其方法定義如下:(1)public void ad

46、dFirst(E element)將指定元素插入此列表的開頭。 (2)public void addLast(E element) 將指定元素添加到此列表的結(jié)尾。 (3)public E removeFirst() 移除并返回此列表的第一個(gè)元素。(4)public E removeLast()移除并返回此列表的最后一個(gè)元素?!纠?-12】 LinkedListDemo.java LinkedList類應(yīng)用1 import java.util.LinkedList;2 public class LinkedListDemo3 public static void main(String args

47、)4 LinkedList queue=new LinkedList();5 queue.addFirst(set);6 queue.addLast(HashSet);7 queue.addLast(TreeSet);8 queue.addFirst(List);9 queue.addLast(ArrayList);10 queue.addLast(LinkedList);11 queue.addLast(map);12 queue.addFirst(collection);13 System.out.println(queue);14 queue.removeLast();15 queue.

48、removeFirst();16 System.out.println(queue);17 18 輸出結(jié)果:D:JAVA8java LinkedListDemocollection, List, set, HashSet, TreeSet, ArrayList, LinkedList, mapList, set, HashSet, TreeSet, ArrayList, LinkedList程序分析: 上述程序的第4行創(chuàng)建了一個(gè)LinkedList類型的對象queue,并指定其存放的元素類型為String。第5行通過addFirst() 方法在queue中的隊(duì)首放置元素set,第6行通過addLast()方法向queue中添加元素HashSet,該元素位于set元素的后面。第7行通過addLast()方法向queue中添加元素TreeSet,該元素位于HashSet元素的后面。第8行通過addFirst()方法向queue中添加元素List,該元素位于set元素的前面。第911行分別通過addLast()方法在元素TreeSet后面依次添加了“

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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

提交評論