黑马程序员_泛型
--------------------ASP.Net+Android+IOS開發(fā)、.Net培訓(xùn)、期待與您交流! --------------------
?
1.???? 泛型
???? 1.概述
?
?????????? 泛型是為了解決了集合中存儲對象安全問題,如果集合中存數(shù)了不同類型的對象,那么讀取出來后,操作取出的對象以為不知道類型,會出現(xiàn)安全問題,但是這不會在編譯時期提示錯誤,而是會在運(yùn)行時期出現(xiàn)問題,所以泛型會把運(yùn)行時期的錯誤移到了編譯時期,那么錯誤就會避免。
???? 2.集合中的泛型
?????????? 在集合中都會存在泛型,下同時迭代器中也定義了泛型,在讀取出來后,我們也要指定迭代器的類型,這樣我們就不需要強(qiáng)制類型轉(zhuǎn)換了,因?yàn)榈髦芯椭付祟愋?#xff0c;所以讀取出來的對象類型也就是我們指定的類型。
?
?
package www.fuxi.jihe;import java.util.ArrayList; import java.util.Iterator;public class fanxingDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<String>();list.add("zhangsan");// 在這里必須傳入的String對象,如果不是那么編譯會出錯誤list.add("lisi");Iterator<String>it = list.iterator();// 在這里也要指定迭代器的類型while (it.hasNext()) {String s = it.next();// 在這里不需要強(qiáng)制類型轉(zhuǎn)換為String了,因?yàn)榈饕呀?jīng)指定了類型System.out.println(s);}}} 結(jié)果: zhangsan lisi?
?
?
2.???? 自定義泛型類
自定義的泛型類,可以按照我們隨意要求指定類型
?
?
package www.fuxi.jihe;/*** 在此類型定義了一個泛型,這個字母可以隨便定義當(dāng)創(chuàng)建了此類的對象,那么就需要指定泛型的類型,那么里面的成員泛型就統(tǒng)一指定了*/ package www.fuxi.jihe;public class Demo<T> {private T t;public void set(T t){//此方法是和類上的泛型一起變化this.t=t;System.out.println("set:"+t);}public static void main(String [] agrs){Demo<String> d=new Demo<String>();d.set("123");}} 結(jié)果: set:123?
?
3.???? 泛型方法
1.???? 一個泛型
???
public class Demo<T> {public void show(T t) {System.out.println("show:" + t);}public void print(T t) {System.out.println("print:" + t);}public static void main(String[] args) {Demo<String> d = new Demo<String>();d.show("hello");d.print("world");// d.show(new// Integer(2));//在這里編譯出錯,因?yàn)閐對象泛型已經(jīng)指定了是String類型,所以參數(shù)全部是String類型System.out.println("-----------");Demo<Integer> d1 = new Demo<Integer>();d1.show(new Integer(3));d1.print(new Integer(6));}} 結(jié)果: show:hello print:world ----------- show:3 print:6?
?
?
2.???? 多個泛型
?
?
package www.fuxi.jihe;public class Demo<T> {public void set(T t){//此方法是和類上的泛型一起變化System.out.println("set:"+t);}public <Q> void get(Q q){//此方法上的泛型是和類上的泛型無關(guān),可以是任意類型System.out.println("get:"+q);}public static void main(String [] agrs){Demo<String> d=new Demo<String>();d.set("123");d.get("abc");d.get(5);}}結(jié)果: set:123 get:abc get:5?
從結(jié)果可以看出,這個類中既有和類上的泛型一起變化的,也有自己特有的方法,例如:get()方法上的泛型,可以和類上的一樣也可以不一樣。
?
3.靜態(tài)方法上的泛型
? 把泛型定義在返回值和修飾符之間
靜態(tài)方法上的泛型的定義需要自己定義,不要和類上的泛型統(tǒng)一,因?yàn)殪o態(tài)方法只要是類一加載就生成,如果和類上的泛型統(tǒng)一的話,在靜態(tài)方法加載的時候,沒有對象生成,也就沒有指定泛型的類型,那么就會出錯,這些都和泛型定義出現(xiàn)的時間有關(guān)。
?
?
package www.fuxi.jihe;public class Demo<T> {public static <Q> void show(Q q){//這里不要和類上的泛型統(tǒng)一System.out.println("show:"+q);}public static void main(String [] agrs){Demo.show("hello");}} 結(jié)果: show:hello?
4.???? 接口泛型
???? 在接口上自定義泛型
?
?
package www.fuxi.jihe;interface inter<T> {void show(T t); }/* 第一種實(shí)現(xiàn)泛型接口,在接口上指定泛型類型 */ public class Demo implements inter<String> {public void show(String t) {System.out.println("show:" + t);}public static void main(String[] agrs) {Demo d = new Demo();d.show("hellowrold");} } 結(jié)果: show:hello world?
?
下面是在對象是上指定泛型類型
?
?
package www.fuxi.jihe;interface inter<T> {void show(T t); }/* 第二種實(shí)現(xiàn)泛型接口,在接口上不定義泛型,而是在對象上指定泛型類型 */ public class Demo<T> implements inter<T> {public void show(T t) {System.out.println("show:" + t);}public static void main(String[] agrs) {Demo<Integer> d = new Demo<Integer>();d.show(3);} }結(jié)果: show:3?
5.???? 泛型的高級應(yīng)用
1.???? 通配符
通配符用?表示,也叫占位符,可以表示任意類型
?
?
package www.fuxi.jihe;import java.util.ArrayList; import java.util.Iterator;public class Demo {/*在這里泛型類型使用通配符表示,表次是此可以傳入任意類型*/public void show(ArrayList<?> list) {Iterator<?> it = list.iterator();while (it.hasNext()) {System.out.println(it.next());}}public static void main(String[] agrs) {Demo d = new Demo();ArrayList<String> l1 = new ArrayList<String>();l1.add("abc");l1.add("123");l1.add("ased");d.show(l1);System.out.println("---------");ArrayList<Integer> l2 = new ArrayList<Integer>();l2.add(1);l2.add(2);l2.add(3);d.show(l2);} } 結(jié)果: abc 123 ased --------- 1 2 3?
?
但是也可以使用另一中方式表示,但是其有缺點(diǎn),不能表示一個范圍類型,通配符可以表示一個類型范圍,詳細(xì)“2.參考通配符設(shè)置上下限”
?
?
package www.fuxi.jihe;import java.util.ArrayList; import java.util.Iterator;public class Demo {/* 在這里泛型類型使用通配符表示,表次是此可以傳入任意類型 */public <T> void show(ArrayList<T> list) {Iterator<T> it = list.iterator();while (it.hasNext()) {T t= it.next();System.out.println(t);}}public static void main(String[] agrs) {Demo d = new Demo();ArrayList<String> l1 = new ArrayList<String>();l1.add("abc");l1.add("123");l1.add("ased");d.show(l1);System.out.println("---------");ArrayList<Integer> l2 = new ArrayList<Integer>();l2.add(1);l2.add(2);l2.add(3);d.show(l2);} }結(jié)果: abc 123 ased --------- 1 2 3?
從結(jié)果上可以看出,結(jié)果和使用通配符是一樣的,這個好處可以把對象取出來,可以進(jìn)行操作,T t= it.next();但是使用通配符的話,就不能進(jìn)行此操作,但是通配符可以設(shè)置上下限。
2.???? 通配符設(shè)置上下限
? extends E :?表示可以是E類型或者是E的子類,這是設(shè)置的上限
? super E:?表示的可以是E類型或者E的父類類型,這是設(shè)置的下限
?
設(shè)置上限
?
?
package www.fuxi.jihe;import java.util.ArrayList; import java.util.Iterator;class door {privateString name;publicdoor(String name) {this.name= name;}publicString toString() {returnthis.name;} }class tieDoor extends door {// 繼承了door類publictieDoor(String name) {super(name);} }public class fanxingDemo {publicvoid show(ArrayList<? extends door> list) {// 設(shè)置類泛型的限,可以是door類型或者是door的子類型Iterator<?extends door> it = list.iterator();while(it.hasNext()) {System.out.println(it.next());}}publicstatic void main(String[] args) {fanxingDemod = new fanxingDemo();ArrayList<tieDoor>list = new ArrayList<tieDoor>();list.add(newtieDoor("door-1"));list.add(newtieDoor("door-2"));list.add(newtieDoor("door-3"));d.show(list);}} 結(jié)果: door-1 door-2 door-3?
?
設(shè)置下限:
?
TreeSet(Comparator<?super E>?comparator)
??????????構(gòu)造一個新的空 TreeSet,它根據(jù)指定比較器進(jìn)行排序。
我們就根據(jù)這個比較器看看設(shè)置下限:
?
package www.fuxi.jihe;import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet;class door {privateString name;publicdoor(String name) {this.name= name;}publicString toString() {returnthis.name;}publicString getName(){returnthis.name;} }class tieDoor extends door {// 繼承了door類publictieDoor(String name) {super(name);} }class MyCom implements Comparator<door>{publicint compare(door o1, door o2) {returno1.getName().compareTo(o2.getName());}} public class fanxingDemo {publicstatic void main(String[] args) {fanxingDemod = new fanxingDemo();TreeSet<tieDoor>list = new TreeSet<tieDoor>(new MyCom());list.add(newtieDoor("door-3"));list.add(newtieDoor("door-1"));list.add(newtieDoor("door-2"));Iterator<tieDoor>it=list.iterator();while(it.hasNext()){System.out.println(it.next());}}} 結(jié)果: door-1 door-2 door-3?
從結(jié)果可以看出,已經(jīng)比較了,但是設(shè)置的比較器是父類型,但是TreeSet集合設(shè)置的door的子類型,也可以排序,就是可以是下限或者是下限的父類型
可以是tieDoor類型或者tieDoor的父類型,都可以進(jìn)行比較
假如又有一個類繼承了door類,那么此子類對象添加到在TreeSet中,也可以使用當(dāng)前的比較器進(jìn)行排序。
--------------------ASP.Net+Android+IOS開發(fā)、.Net培訓(xùn)、期待與您交流! --------------------
總結(jié)
- 上一篇: 梦到蛇头预示着什么
- 下一篇: sql2008 获取表结构说明