java中的泛型
** * 泛型<>: * jdk1.5出現 的安全機制 * 注意:泛型裏全放的是引用類型的數據,不能放基本數據類型。 * 好處: * 1.將運行時期的問題ClassCastException轉到了編譯時期 * 2.避免了轉換的麻煩 * <>什麼時候用,當操作的引用數據類型不確定 的時候,就使用<>。將要操作的引用數據類型傳入即可 * 其實<>就是一個用於接收具體 引用數據類型的參數範圍 * * 在程序中,只要用到了帶有<>的類或者接口,就要明確傳入的具體引用數據類型 * 泛型技術 是給編譯器使用的技術,用於編譯時期,確保了類型的安全 * 運行時,會將泛型去掉,生成的class文件中是不帶泛型的。這個稱爲泛型的擦除。 * 因爲爲了兼容運行時的類加載器。 * 泛型的補償:在運行時,通過 獲取元素的類型進行轉換動作,不用使用者再強制轉換了 * * 在jdk1.5後,使用泛型來接收類中要操作的引用數據類型 * 泛型類,什麼時候 用?當類中的操作的引用數據不確定 的時候 ,就使用泛型 來表示 * * 泛型的通配符:?未知類型 * * 迭代集合中元素 * 可以對類型進行限定: * ?extends E:接收E類型或者E的子類型對象 ,這叫上限 * ? super E:接收E類型或者E的父類型。下限 */ 一,泛型作用在集合中 // 示例一:
public class GenericDemo { public static void main(String[] args){ test1(); test2(); test3(); } private static void test3() { ArrayList<String> arrayList = new ArrayList<String>(); arrayList.add("aaaa"); arrayList.add("aaaa"); arrayList.add("aaaa"); // Iterator<String> iterator = arrayList.iterator(); // while (iterator.hasNext()){ // String str = iterator.next(); // System.out.println(str); // } iter(arrayList); } //TreeSet private static void test2() { TreeSet<Person> treeSet = new TreeSet<Person>(); treeSet.add(new Person("zhangsan", 10)); treeSet.add(new Person("lisi", 20)); treeSet.add(new Person("wangwu", 20)); treeSet.add(new Person("angwu", 20)); treeSet.add(new Person("zhaoliu", 30)); treeSet.add(new Person("houqi", 30)); iter(treeSet); } private static void test1() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("aaaa"); arrayList.add("bbb"); arrayList.add("ccc"); arrayList.add("ddd"); iter(arrayList); } //利用泛型封裝成共性方法 private static<T> void iter(Collection<T> treeSet) { Iterator<T> iterator = treeSet.iterator(); while (iterator.hasNext()){ T t = iterator.next(); System.out.println(t); } } }示例一打印的結果爲:
aaaa
bbb
ccc
ddd
--------------------------
zhangsan:10
angwu:20
lisi:20
wangwu:20
houqi:30
zhaoliu:30
--------------------------
aaaa
aaaa
aaaa
二,泛型作用在類和方法上
示例二:// 工具類中帶有泛型
public class Tool<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } //將泛型定義 在方法上 public <R>void show(R str){ System.out.println("show"+str); } //當方法靜態時,不能訪問類上定義 的泛型,如果靜態方法使用泛型 ,只能將泛型定義在方法上 public static<Y> void method(Y obj){ System.out.println("method..."+obj); } }
public class GenericDemo2 { public static void main(String[] args){ Tool<Worker> tool = new Tool<Worker>(); tool.setT(new Worker("jjj",22)); Worker worker = (Worker) tool.getT(); System.out.println(worker); Tool<String> tool1 = new Tool<>(); tool1.show(new Integer(5)); Tool.method("haha"); } }示例二打印的結果爲:
Worker...jjj:22
show5
method...haha
三,泛型作用在接口上
示例三:接口中帶有泛型
public interface Inter<T> { public void show(T t); } class InterImpl2<T> implements Inter<T>{ @Override public void show(T t) { System.out.println("show:"+t); } } class InterImpl implements Inter<String>{ @Override public void show(String s) { System.out.println("str:"+s); } }
public class GenericDemo3 { public static void main(String[] args){ InterImpl inter = new InterImpl(); inter.show("hdha"); InterImpl2 <String>interImpl2 = new InterImpl2<String>(); interImpl2.show("jjj"); } }示例三打印結果爲:
str:hdha
show:jjj
四,泛型的通配符,泛型的上限,泛型的下限
//示例四:泛型的通配符
public class GenericAdvanceDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); HashSet<Integer> list2 = new HashSet<>(); list2.add(22); list2.add(33); iteratCollection(list); iteratCollection(list2); } private static void iteratCollection(Collection<?> list) { Iterator<?> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } } 打印結果爲: aaa bbb 33 22示例五:泛型的上限和下限
public class GenericAdvanceDemo3 { public static void main(String[] args) { ArrayList<Worker> list = new ArrayList<>(); list.add(new Worker("aaa", 22)); list.add(new Worker("bbb", 20)); ArrayList<Person> list2 = new ArrayList<>(); list2.add(new Worker("aaa", 22)); list2.add(new Worker("bbb", 20)); ArrayList<Student> list3 = new ArrayList<>(); list3.add(new Student("aaa", 22)); list3.add(new Student("bbb", 20)); list2.addAll(list3); iteratCollection(list2); iteratCollection2(list2); } //上限 private static void iteratCollection(Collection<? extends Person> list) { Iterator<? extends Person> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("----------------------"); } //下限
private static void iteratCollection2(Collection<? super Person> list) { Iterator<? super Person> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("----------------------"); } //一般在存儲元素的時候 都使用上限,因爲這樣取出都 是按照上限類型來運算的,不會出現安全隱患 class MyCollection<E>{ public void add(E e){ } public void addAll(MyCollection<? extends E> e){ } }} 打印結果爲:
Worker...aaa:22
Worker...bbb:20
Student...aaa:22
Student...bbb:20
----------------------
Worker...aaa:22
Worker...bbb:20
Student...aaa:22
Student...bbb:20
----------------------
示例六:泛型的下限使用
在使用TreeSet時,一定要使用比較器
public class GenericAdvanceDemo4 { public static void main(String[] args) { TreeSet<Worker> list = new TreeSet<>(); list.add(new Worker("bbb", 20)); list.add(new Worker("aaa", 22)); list.add(new Worker("ccc", 20)); TreeSet<Person> list2 = new TreeSet<>(new CompByName()); list2.add(new Worker("bbb", 20)); list2.add(new Worker("aaa", 22)); list2.add(new Worker("ccc", 20)); TreeSet<Student> list3 = new TreeSet<>(); list3.add(new Student("bbb", 20)); list3.add(new Student("aaa", 22)); list3.add(new Student("ccc", 20)); Iterator<Person> iterator = list2.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } } /** * class TreeSet<Worker>{ * Tree(Comparator<? super Worker>); * 什麼時候用下限呢,通常參集合中的元素進行取出操作時,可以使用下限 * } */ class CompByName implements Comparator<Person> { @Override public int compare(Person person, Person t1) { int temp = person.getName().compareTo(t1.getName()); return temp == 0 ? person.getAge() - t1.getAge() : temp; } }