第七講容器和泛型_第1頁(yè)
第七講容器和泛型_第2頁(yè)
第七講容器和泛型_第3頁(yè)
第七講容器和泛型_第4頁(yè)
第七講容器和泛型_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第7講

容器與泛型容器容器是用于存儲(chǔ)并操作多個(gè)元素的對(duì)象一個(gè)容器框架通常包括一組接口抽象的數(shù)據(jù)類型允許對(duì)容器以獨(dú)立于具體實(shí)現(xiàn)的統(tǒng)一方式進(jìn)行操作具體實(shí)現(xiàn)采用不同的數(shù)據(jù)結(jié)構(gòu)對(duì)接口的具體實(shí)現(xiàn)算法一組有用的算法,如查找、排序算法針對(duì)通用接口Java容器類位于java.util包中用于保存對(duì)象封裝了眾多的數(shù)據(jù)結(jié)構(gòu)和算法JAVA中的部分容器類圖Collection:獨(dú)立元素的序列List:按照插入的順序保存元素

ArrayList:以動(dòng)態(tài)數(shù)組的方式實(shí)現(xiàn),適用于隨機(jī)訪問(wèn),但插入刪除代價(jià)較高

LinkedList:以鏈表方式實(shí)現(xiàn),插入刪除代價(jià)低,但不適合隨機(jī)訪問(wèn)Set:不能有重復(fù)元素

HashSet:基于散列技術(shù)的實(shí)現(xiàn),元素的順序與插入順序不一致

TreeSet:基于紅黑樹的實(shí)現(xiàn),元素的順序與大小相關(guān)

LinkedHashSet:采用了散列,但同時(shí)維護(hù)了元素的插入順序Queue:按排隊(duì)規(guī)則確定順序

LinkedList:先進(jìn)先出隊(duì)列

PriorityQueue:優(yōu)先隊(duì)列Map:一組成對(duì)的“鍵-值”對(duì)象

HashMap:鍵值按散列技術(shù)排序

TreeMap:鍵值按元素的大小排序

LinkedHashMap:維護(hù)了鍵值的插入順序Collection接口publicinterfaceCollection<E>extendsIterable<E>{intsize();booleanisEmpty();booleancontains(Objectelement);booleanadd(Eelement);booleanremove(Objectelement);Iterator<E>iterator();booleancontainsAll(Collection<?>c);booleanaddAll(Collection<?extendsE>c);booleanremoveAll(Collection<?>c);booleanretainAll(Collection<?>c);voidclear();Object[]toArray();<T>T[]toArray(T[]a);}List接口元素訪問(wèn)Eget(intindex);Eset(intindex,Eelement);boolean

add(Eelement);boolean

add(intindex,Eelement);Eremove(intindex);boolean

addAll(intindex,Collection<?ExtendsE>c);查找

int

indexOf(Objecto);

int

lastIndexOf(Objecto);遍歷

ListIterator<E>listIterator();

ListIterator<E>listIterator(intindex);Range-ViewList<E>subList(intfromintto);List實(shí)現(xiàn)類ArrayListLinkedListVector(deprecated)importjava.util.*;publicclassListPerformance{publicstaticvoidmain(String[]args){Collection<Integer>c=newHashSet<Integer>();c.add(1);c.add(2);List<Integer>list1=newArrayList<Integer>(c);List<Integer>list2=newLinkedList<Integer>(c);

/**比較在表頭插入元素的時(shí)間*/longt1=System.nanoTime();for(inti=0;i<100000;i++)list1.add(2,i);System.out.println(System.nanoTime()-t1);t1=System.nanoTime();for(inti=0;i<100000;i++)list2.add(2,i);System.out.println(System.nanoTime()-t1);

/*比較訪問(wèn)一個(gè)元素的時(shí)間*/Randomrand=newRandom();inttmp;t1=System.nanoTime();for(inti=0;i<100000;i++) tmp=list1.get(rand.nextInt(list1.size()));System.out.println(System.nanoTime()-t1);t1=System.nanoTime();for(inti=0;i<100000;i++) tmp=list2.get(rand.nextInt(list2.size()));System.out.println(System.nanoTime()-t1);}}374213141631015625960258213795528821ArrayList和LinkedList性能比較Set接口

intsize();booleanisEmpty();booleancontains(Objectelement);booleanadd(Eelement);booleanremove(Objectelement);Iterator<E>iterator();booleancontainsAll(Collection<?>c);booleanaddAll(Collection<?ExtendsE>c);booleanremoveAll(Collection<?>c);booleanretainAll(Collection<?>c);voidclear();Object[]toArray();T[]toArray(T[]a);Set實(shí)現(xiàn)類HashSet

基于hash方法的實(shí)現(xiàn)插入的元素不保持順序TreeSet

要求被加入對(duì)象可比較基本類型實(shí)現(xiàn)Comparable接口向TreeSet的構(gòu)造函數(shù)顯式傳入一個(gè)Comparator對(duì)象,用于比較被加入對(duì)象LinkedHashSet

基于hash方法的實(shí)現(xiàn)但保持元素插入的順序importjava.util.*;publicclassSetOperations{ publicstaticvoidmain(String[]args){ Collection<Integer>c=newArrayList<Integer>(); c.add(43); c.add(34); c.add(34); c.add(28); c.add(56); c.add(56); c.add(17); Set<Integer>s1=newHashSet<Integer>(); Set<Integer>s2=newTreeSet<Integer>(); Set<Integer>s3=newLinkedHashSet<Integer>(); s1.addAll(c); s2.addAll(c); s3.addAll(c); System.out.println(c); System.out.println(s1); System.out.println(s2); System.out.println(s3); }}輸出:[43,34,34,28,56,56,17][17,34,43,56,28][17,28,34,43,56][43,34,28,56,17]importjava.util.*;classPerson{ Stringname; intsalary; publicPerson(Stringname,intsalary){=name;this.salary=salary;} publicStringtoString(){ return"Name="+name+",Salary="+salary; }}publicclassTreeSetTest1{ publicstaticvoidmain(String[]args){ Personp1=newPerson("Tom",1000); Personp2=newPerson("Bob",2000); Personp3=newPerson("Alice",3000); Set<Person>persons=newTreeSet<Person>(); persons.add(p1);

persons.add(p2);

//

運(yùn)行時(shí)會(huì)報(bào)錯(cuò),因?yàn)闊o(wú)法比較對(duì)象大小 persons.add(p3); System.out.println(persons); }}Exceptioninthread"main"java.lang.ClassCastException:.njnu.cs.abyssoop.ch11.Personcannotbecasttojava.lang.Comparableatjava.util.TreeMap.put(UnknownSource)atjava.util.TreeSet.add(UnknownSource)at.njnu.cs.abyssoop.ch11.TreeSetTest2.main(TreeSetTest1.java:19)importjava.util.*;classPersonimplementsComparable{//方法一:為需要排序的類實(shí)現(xiàn)Comparable接口 Stringname; intsalary; publicPerson(Stringname,intsalary){=name;this.salary=salary;} publicintcompareTo(Objectobj){ Personp=(Person)obj; returnpareTo(); } publicStringtoString(){ return"Name="+name+",Salary="+salary; }}publicclassTreeSetTest2{ publicstaticvoidmain(String[]args){ Set<Person>persons=newTreeSet<Person>(); Personp1=newPerson("Tom",1000); Personp2=newPerson("Bob",2000); Personp3=newPerson("Alice",1500); persons.add(p1); persons.add(p2); persons.add(p3); System.out.println(persons); }}[Name=Alice,Salary=1500,Name=Bob,Salary=2000,Name=Tom,Salary=1000]importjava.util.*;publicclassTreeSetTest3{publicstaticvoidmain(String[]args){ Personp1=newPerson("Tom",1000); Personp2=newPerson("Bob",2000); Personp3=newPerson("Alice",3000); Set<Person>persons1=newTreeSet<Person>(

newComparator<Person>(){//方法二:向TreeSet構(gòu)造函數(shù)傳入//Comparator對(duì)象,用于比較兩個(gè)待排序的對(duì)象; publicintcompare(Personp1,Personp2){ returnpareTo(); } }); persons1.add(p1); persons1.add(p2); persons1.add(p3); Set<Person>persons2=newTreeSet<Person>( newComparator<Person>(){//另一種對(duì)Person排序的方法 publicintcompare(Personp1,Personp2){ return(p1.salary==p2.salary)?0:(p1.salary>p2.salary?1:-1); } }); persons2.add(p1); persons2.add(p2); persons2.add(p3); System.out.println(persons1); System.out.println(persons2);}}[Name=Alice,Salary=3000,Name=Bob,Salary=2000,Name=Tom,Salary=1000][Name=Tom,Salary=1000,Name=Bob,Salary=2000,Name=Alice,Salary=3000]Queue接口方法

boolean

offer(Eo):將給定元素插入隊(duì)列Eremove():獲得并刪除隊(duì)列頭元素,如果隊(duì)列為空,則拋出異常Epoll():獲取并刪除隊(duì)列頭元素,如果隊(duì)列為空,則返回null.Eelement():獲取但不刪除隊(duì)列頭元素,如果隊(duì)列頭為空,則拋出異常Epeek():獲取但不刪除隊(duì)列頭元素,如果隊(duì)列為空,則返回null實(shí)現(xiàn)類

LinkedList

PriorityQueue要求加入的對(duì)象可比較importjava.util.*;publicclassQueueTest1{ publicstaticvoidprintQ(Queue<Integer>queue){ while(queue.peek()!=null) System.out.print(queue.remove()+""); System.out.println(); } publicstaticvoidmain(String[]args){

Queue<Integer>queue=newLinkedList<Integer>();//LinkedList是一種

//先進(jìn)先出對(duì)列; Randomrand=newRandom(); for(inti=0;i<10;i++) queue.offer(rand.nextInt(i+10)); printQ(queue);queue=newPriorityQueue<Integer>();//PriorityQueue是優(yōu)先隊(duì)列; for(inti=0;i<10;i++) queue.offer(rand.nextInt(i+10)); printQ(queue); }}8585691421632566788111212Stack類方法

booleanempty():測(cè)試堆棧是否為空

Epeek():查看棧頂元素而不移除它,若堆棧為空,則拋出EmptyStackException異常Epop():移除棧頂元素并作為此函數(shù)的值返回該對(duì)象,若堆棧為空,則拋出EmptyStackException異常

Epush(Eitem):把項(xiàng)壓入棧頂

int

search(Objecto):返回對(duì)象在棧中的位置,以1為基數(shù)Map接口public

interfaceMap<K,V>{Vput(Kkey,Vvalue);Vget(Objectkey);Vremove(Objectkey);

booleancontainsKey(Objectkey);

booleancontainsValue(Objectvalue);

intsize();

booleanisEmpty();

voidputAll(Map<?extendsK,?extendsV>m);

voidclear();

publicSet<K>keySet();

publicCollection<V>values();

publicSet<Map.Entry<K,V>>entrySet();public

interfaceEntry{KgetKey();VgetValue();VsetValue(Vvalue);}}Map實(shí)現(xiàn)類HashMapTreeMapLinkedHashMapitem2=Jordon;item4=Alice;item1=Tom;item3=Bob;item5=Green;item1=Tom;item2=Jordon;item3=Bob;item4=Alice;item5=Green;item4=Alice;item3=Bob;item1=Tom;item2=Jordon;item5=Green;/*不同的Map的行為*/importjava.util.*;publicclassMapTest1{publicstaticvoidmain(String[]args){ Map[]maps={newHashMap(),newTreeMap(),newLinkedHashMap()}; for(inti=0;i<maps.length;i++){ maps[i].put("item4","Alice"); maps[i].put("item3","Bob"); maps[i].put("item1","Tom"); maps[i].put("item2","Jordon"); maps[i].put("item5","Green"); } for(inti=0;i<maps.length;i++){ Iteratoriter=maps[i].keySet().iterator(); while(iter.hasNext()){ Stringkey=(String)iter.next(); Stringvalue=(String)maps[i].get(key); System.out.print(key+"="+value+";"); } System.out.println(); }}}Collection的公共方法add(E)addAll(collection<?ExtendsE>)remove(Object)removeAll(Collection<?>)contains(Object)iterator()containsAll(Collection<?>)retainAll(Collection<?>)Size()toArray()contains方法的實(shí)現(xiàn)語(yǔ)義List基于equals()方法HashSet同時(shí)基于hashCode()和equals()方法TreeSet基于compareTo()結(jié)果importjava.util.*;classPersonimplementsComparable{Stringname;intage;publicPerson(Stringname,intage){=name;this.age=age;}

/*equals()方法影響List和HashSet的contains()方法;包括HashMap的鍵的比較*/publicbooleanequals(Objecto){if(!(oinstanceofPerson))returnfalse;Personp=(Person)o;returnname.equals()&&age==p.age;}/*hashCode()方法是基于HASH的HashMap和HashSet用于產(chǎn)生HASH值的基本方法*/publicinthashCode(){return(name+age).hashCode();}/*compareTo()方法是TreeSet的contains()方法比較對(duì)象是否相等的依據(jù)*/publicintcompareTo(Objectobj){Personp=(Person)obj;if(pareTo()>0)returnpareTo();else return(age>p.age)?1:(age==p.age?0:-1);}}publicclassContainsTest{publicstaticvoidmain(String[]args){Personp1=newPerson("Alice",21);Personp2=newPerson("Bob",22);Personp3=newPerson("Bob",22);Collection<Person>c1=newArrayList<Person>();c1.add(p1);c1.add(p2);System.out.println(c1.contains(p2));System.out.println(c1.contains(p3));Collection<Person>c2=newHashSet<Person>();c2.add(p1);c2.add(p2);

System.out.println(c2.contains(p3));

Collection<Person>c3=newTreeSet<Person>();c3.add(p1);c3.add(p2);

System.out.println(c3.contains(p3));

Map<Person,String>map=newHashMap<Person,String>();map.put(p1,"Alice");map.put(p2,"Bob");map.put(p3,"Bob");

System.out.println(map);}}truetruetruetrue{Person@2cb6949f=Alice,Person@3d5fa95=Bob}迭代器Iterator用于遍歷任何Collection容器的對(duì)象publiciterator()返回Iterator對(duì)象Iterator的方法

hasNext()方法檢測(cè)序列中是否還有元素next()方法返回下一個(gè)元素remove()方法將迭代器新近返回的元素刪除/*采用迭代器遍歷容器的元素*/importjava.util.*;publicclassCollectionTest{ publicstaticvoidmain(String[]args) { Collection<String>coll=newArrayList<String>(); coll.add("Hi,Tom!"); coll.addAll(Arrays.asList("WelcometoJava!".split(""))); Iterator<String>iter=coll.iterator(); while(iter.hasNext()){ System.out.println(iter.next()); } }}輸出:Hi,Tom!WelcomeToJava!foreach語(yǔ)法用于遍歷數(shù)組、集合等元素,是for語(yǔ)句的特殊版本語(yǔ)法:for(Tval:objs){…}應(yīng)用場(chǎng)合數(shù)組publicstaticvoidmain(String[]args){

for(String

arg:args){

System.out.println(arg);}}容器(實(shí)現(xiàn)了Iterable接口)Collection<String>col=newArrayList<String>();for(String

str:col)

System.out.println(str);任何實(shí)現(xiàn)了Iterable接口的對(duì)象Iterable接口包含一個(gè)方法Iterator

iterator();importjava.util.*;publicclassIterableClassimplementsIterable<String>{//實(shí)現(xiàn)Iterable接口protectedString[]words=("Andthatishow"+"weknowtheEarthtobebanana-shapped.").split("");

publicIterator<String>iterator(){//Iterable接口需要實(shí)現(xiàn)的方法returnnewIterator<String>(){//采用匿名內(nèi)部類生成一個(gè)Iterator對(duì)象 privateintindex=0;

publicbooleanhasNext(){ returnindex<words.length; } publicStringnext(){ returnwords[index++]; } publicvoidremove(){ thrownewUnsupportedOperationException(); }};}publicstaticvoidmain(String[]args){ for(Strings:newIterableClass())//可以使用foreach語(yǔ)法 System.out.print(s+""); System.out.println();}}Collections實(shí)用類包含一組作用于集合的實(shí)用靜態(tài)方法/算法

addAll()fill()reverse()binarySearch()max()min()frequency()shuffle()sort()泛型泛型的概念泛型類/接口泛型方法泛型邊界和類型擦除通配符泛型概念提高代碼復(fù)用能力同一個(gè)類型定義、數(shù)據(jù)結(jié)構(gòu)或算法等適用于許多種類型解耦類或方法所使用的類型之間的約束增強(qiáng)編譯器類型檢查功能泛型出現(xiàn)之前,容器類可以存放任何Object對(duì)象,由程序員負(fù)責(zé)將對(duì)象向下轉(zhuǎn)型為具體的類,這種缺乏編譯期檢查的行為容易產(chǎn)生運(yùn)行時(shí)錯(cuò)誤importjava.util.*;classFruit{}classAppleextendsFruit{}classOrangeextendsFruit{}publicclassBeforeGenerics{publicstaticvoidmain(String[]args){ Listlist=newArrayList(); list.add(newApple()); list.add(newOrange()); Iteratoriter=list.iterator(); while(iter.hasNext()){ Appleapple=(Apple)iter.next();//運(yùn)行時(shí)異常,編譯期不出錯(cuò)

}}}問(wèn)題:如果我們想執(zhí)行嚴(yán)格的編譯器檢查,以使得容器只能存放特定的類型,該怎么辦?泛型類/接口泛型語(yǔ)法

classname<T1,T2,…,Tn>{/*…*/}interfacename<T1,T2,…,Tn>{/*…*/}

類/接口定義后面加參數(shù)列表,用<>表示,參數(shù)列表可以有一個(gè)或多個(gè)public

classBox{

privateObjectobject;

public

voidset(Objectobject){

this.object=object;}

publicObjectget(){returnobject;}}/***GenericversionoftheBoxclass.*@param<T>thetypeofthevaluebeingboxed*/public

classBox<T>{//Tstandsfor"Type"

privateTt;

public

voidset(Tt){this.t=t;}

publicTget(){returnt;}}泛型類/接口實(shí)例化定義類型時(shí)用具體的類型實(shí)例化類型參數(shù)

Box<Integer>integerBox=newBox<Integer>();List<Apple>list1=newArrayList<Apple>();List<Orange>list2=newArrayList<Orange>();list1.add(newApple());

//list1.add(newOrange());//編譯期錯(cuò)誤,無(wú)法添加Orange對(duì)象至該容器public

interfacePair<K,V>{

publicKgetKey();

publicVgetValue();}public

classOrderedPair<K,V>implementsPair<K,V>{

privateKkey;

privateVvalue;

publicOrderedPair(Kkey,Vvalue){this.key=key;this.value=value;}

publicKgetKey(){returnkey;}

publicVgetValue(){returnvalue;}}Pair<String,Integer>p1=newOrderedPair<String,Integer>("Even",8);Pair<String,String>p2=newOrderedPair<String,String>("hello","world");同一份代碼,可以用于處理不同類型的對(duì)象,并保持了編譯器的類型檢查的優(yōu)點(diǎn)泛型的繼承/實(shí)現(xiàn)與普通類的類繼承和接口實(shí)現(xiàn)一樣繼承:extends實(shí)現(xiàn):implementsclassTwoTuple<A,B>{publicfinalAfirst;publicfinalBsecond;publicTwoTuple(Aa,Bb){first=a;second=b;}publicStringtoString(){return"("+first+","+second+")";}}classThreeTuple<A,B,C>extendsTwoTuple<A,B>{//ThreeTuple繼承自TwoTuplepublicfinalCthird;publicThreeTuple(Aa,Bb,Cc){super(a,b);third=c;}publicStringtoString(){return"("+first+","+second+","+third+")";}}publicclassTupleTest{publicstaticvoidmain(String[]args){TwoTuple<Integer,String>tuple1=newTwoTuple<Integer,String>(1,"TwoTuple");ThreeTuple<Boolean,Double,String>tuple2=newThreeTuple<Boolean,Double,String>(true,1.34,"ThreeTuple");System.out.println(tuple1);System.out.println(tuple2);}}(1,TwoTuple)(true,1.34,ThreeTuple)泛型類繼承示例Java.util中的泛型類繼承和實(shí)現(xiàn)例子publicinterfaceIterable<E>{…}publicinterfaceCollection<E>extendsIterable<E>{…}publicinterfaceList<E>extendsCollection<E>{…}publicabstractclassAbstractCollection<E>implementsCollection<E>{…}publicabstractclassAbstractList<E>extendsAbstractCollection<E>implementsList<E>{…}publicclassArrayList<E>extendsAbstractList<E>implementsList<E>,RandomAccess,Cloneable,java.io.Serializable{…}interfaceGenerator<T>{Tnext();}//泛型接口;publicclassFibonacciimplementsGenerator<Integer>{//用實(shí)際類型實(shí)例化后的具體接口privateintcount=0;

publicIntegernext(){returnfib(count++);}//Generator<Integer>接口需要實(shí)現(xiàn)的方法privateintfib(intn){if(n<2)return1;returnfib(n-1)+fib(n-2);}publicstaticvoidmain(String[]args){Fibonaccigen=newFibonacci();for(inti=0;i<18;i++)System.out.println(gen.next()+"");}}泛型方法語(yǔ)法:將泛型參數(shù)列表置于返回值之前

public<T>voidf(Tx){}類型參數(shù)推測(cè)使用泛型方法時(shí),不必要指明參數(shù)類型,編譯器會(huì)自動(dòng)依據(jù)傳遞的參數(shù)進(jìn)行類型推測(cè),就好象f()被重載過(guò)無(wú)數(shù)次泛型方法參數(shù)推測(cè)publicclassGenericMethods{public<T>voidf(Tx){ System.out.println(x.getClass().getName());}publicstaticvoidmain(String[]args){GenericMethodsgm=newGenericMethods();gm.f("");gm.f(1);gm.f(1.0);gm.f(1.0F);gm.f('c');gm.f(gm);}}java.lang.Stringjava.lang.Integerjava.lang.Doublejava.lang.Floatjava.lang.Character.njnu.cs.abyssoop.ch15.GenericMethods[A][A,B,C][,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]importjava.util.*;publicclassGenericVarargs{publicstatic<T>List<T>makeList(T...args){//可變參數(shù),…表示參數(shù)可以是一個(gè)T類

//型數(shù)組或是T類型的對(duì)象序列,只能用于最后一個(gè)參數(shù)List<T>result=newArrayList<T>();for(Titem:args)//foreach語(yǔ)法遍歷可變參數(shù)result.add(item);returnresult;}publicstaticvoidmain(String[]args){List<String>ls=makeList("A");System.out.println(ls);ls=makeList("A","B","C");System.out.println(ls);ls=makeList("ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""));System.out.println(ls);}}泛型方法與可變參數(shù)邊界和類型擦除泛型類定義內(nèi)部,所有的參數(shù)類型都只是作為Object類,丟失了具體的類型信息類型擦除用具體類型實(shí)例化類型參數(shù)不會(huì)使得泛型類感知具體的類型classHasF{publicvoidf(){System.out.println("HasF.f()");}}classManipulator<T>{privateTobj;publicManipulator(Tx){obj=x;}publicvoidmanipulate(){obj.f();//編譯時(shí)錯(cuò)誤,f()沒有定義} }publicclassManipulation{publicstaticvoidmain(String[]args){HasFhf=newHasF();Manipulator<HasF>manipulator=newManipulator<HasF>(hf);manipulator.manipulate();}}擦除導(dǎo)致類型信息丟失類型邊界通過(guò)重載的extends關(guān)鍵詞聲明泛型類參數(shù)的類型邊界語(yǔ)法classname<Textendsbaseclass&baseinterface1&baseinterface2&…>可以包含一個(gè)基類和多個(gè)接口,基類在前ClassA{/*...*/}interfaceB{/*...*/}interfaceC{/*...*/}classD<TextendsA&B&C>{/*...*/}classHasF{publicvoidf(){System.out.println("HasF.f()");}}classManipulator<TextendsHasF>{//通過(guò)extends關(guān)鍵詞限定參數(shù)T的界限privateTobj;publicManipulator(Tx){obj=x;}publicvoidmanipulate(){obj.f();//此時(shí)可以調(diào)用f()方法} }publicclassManipulation{publicstaticvoidmain(String[]args){HasFhf=newHasF();Manipulator<HasF>manipulator=newManipulator<HasF>(hf);manipulator.manipulate();}}泛型方法和邊界類型邊界類型對(duì)于實(shí)現(xiàn)某些通用的算法非常有用例如,編寫一個(gè)泛型算法,找出一個(gè)數(shù)組中比給定元素大的元素個(gè)數(shù)public

static<T>intcountGreaterThan(T[]anArray,Telem){

intcount=0;

for(Te:anArray)

if(e>elem)//compilererror,why?++count;

returncount;}public

static<TextendsComparable<T>>intcountGreaterThan(T[]anArray,Telem){

intcount=0;

for(Te:anArray)

if(pareTo(elem)>0)++count;

returncount;}泛型與子類型面向?qū)ο笾?,可以將一個(gè)子類對(duì)象賦值給一個(gè)父類引用對(duì)泛型也適用,可以向一個(gè)存放父類對(duì)象的容器添加子類對(duì)象public

voidsomeMethod(Numbern){/*...*/}someMethod(newInteger(10));//OKsomeMethod(newDouble(10.1));//OKBox<Number>box=newBox<Number>();box.add(newInteger(10));//OKbox.add(newDouble(10.1));//OK泛型與子類型但是不能將一個(gè)存放子類對(duì)象的容器賦值給一個(gè)存放父類對(duì)象的容器即類型參數(shù)的繼承關(guān)系不能拓展到容器的繼承關(guān)系publicvoidboxTest(Box<Number>n){/*...*/}//接受什么類型的參數(shù)?泛型與子類型如果希望編寫一個(gè)方法,能應(yīng)用于下述類型

List<Integer>List<Double>List<Float>List<Byte>List<Number>List<Short>List<Long>How?publicvoid<T>method(List<T>list);//不僅僅能用于上述類型publicvoidmethod(List<Number>list);//只能用于List<Number>類型,無(wú)法用于其它類型通配符上界通配符無(wú)界通配符下界通配符上界通配符如果希望編寫一個(gè)方法,能應(yīng)用于容納Number容器或其子類型的容器,即

List<Number>List<Integer>…解決辦法publicvoidmethod(List<?extendsNumber>list);//泛型參數(shù)的類型可以是Number及其子類型;public

static

doublesumOfList(List<?extendsNumber>list){

doubles=0.0;

for(Numbern:list)s+=n.doubleValue();

returns;}List<Integer>li=Arrays.asList(1,2,3);System.out.println("sum="+sumOfList(li));List<Double>ld=Arrays.asList(1.2,2.3,3.5);System.out.println("sum="+sumOfList(ld));無(wú)界通配符當(dāng)方法實(shí)現(xiàn)只需要用到Object類的方法而無(wú)需用到具體類型的方法,且希望能應(yīng)用于不同類型的容器時(shí),可以用無(wú)界通配符<?>假設(shè),希望寫一個(gè)通用方法,打印容器List中的所有元素public

static

voidprintList(List<Object>list){

for(Objectelem:list)System.out.println(elem+"");System.out.println();}List<Object>list1=newArrayList<Object>();printList(list1);//OKList<Integer>list2=newArrayList<Integer>();printList(list2);//compiletimeerror!public

static

voidprintList(List<?>list){

for(Objectelem:list)System.out.print(elem+"");System.out.println();}List<Object>list1=newArrayList<Object>();printList(list1);//OKList<Integer>list2=newArrayList<Integer>();printList(list2);//OK下界通配符語(yǔ)法:

<?superA>//表示參數(shù)類型為A類型或其父類型例如,要寫一個(gè)方法,能應(yīng)用于所有的Integer類列表容器及其父類的列表容器

List<Integer>List<Number>List<Object>public

static

voidaddNumbers(List<?superInteger>list){

for(inti=1;i<=10;i++){list.add(i);}}List<Integer>list1=newArrayList<Integer>();addNumbers(list1);//OKList<Number>list2=newArrayList<Number>();addNumbers(list2);//OK通配符和繼承當(dāng)沒有通配符時(shí),用具體類型參數(shù)化泛型類型后得到的類型相互之間沒有繼承關(guān)系使用了通配符后,可以在泛型類型之間建立起某種繼承關(guān)系通配符數(shù)組可以將存放子類對(duì)

溫馨提示

  • 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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論