Java集合框架篇Collection—泛型
2018-02-28 20:31
351 查看
泛型
泛型使用
泛型中的符号
泛型的限定
三种使用方式,分别为:泛型类、泛型接口、泛型方法
先举一个例子:
那么它解决了什么问题呢?
再举一个例子:
我们可以看到在编译的时候控制台就会报异常,但是用第二句不用泛型呢,你会看到可以编译通过,控制台之后给你一个不安全操作的提示,但是当你运行的时候一样会报ClassCastException
如果你说你就是要存入不同数据类型的元素,这当然也是可以,但是没啥用,因为元素间不能比较,就只能存进去,然后打印出来。建议用StringBuffer或StringBuilder。
所以泛型首先能够让我们更快的发现解决问题,让运行问题减少,安全。
其次,它避免了强制转换的麻烦。
从它的使用就可以看出<>可以接受一个引用数据类型(注意基础数据类型是不行的)
泛型方法:为了让不同的方法可以操作不同类型,而且类型还不明确,那么可以将泛型定义在方法上。
静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定可以使用泛型方法。
泛型接口:和泛型类作用一样
泛型中还有一个通配符/占位符
泛型属于多态的一种表现形式,所以它也不能预先使用子类其特有的方法。(函数重载、继承/方法重写、运算符重载等一样)
泛型使用
泛型中的符号
泛型的限定
泛型
用于解决安全问题,可以看做一个安全机制三种使用方式,分别为:泛型类、泛型接口、泛型方法
先举一个例子:
ArrayList<String> al = new ArrayList<String>(); //这句话的意思就是,定义了一个ArrayList容器,容器中的元素是String类型
那么它解决了什么问题呢?
再举一个例子:
import java.util.*; class GenericsDemo{ public static void main(String[] args){ ArrayList<String> a1 = new ArrayList<String>(); //ArrayList a1 = new ArrayList(); a1.add("123"); a1.add("312"); a1.add(123); for(Iterator<String> it = a1.iterator();it.hasNext();){ String s = it.next(); System.out.println(s); } } }
我们可以看到在编译的时候控制台就会报异常,但是用第二句不用泛型呢,你会看到可以编译通过,控制台之后给你一个不安全操作的提示,但是当你运行的时候一样会报ClassCastException
如果你说你就是要存入不同数据类型的元素,这当然也是可以,但是没啥用,因为元素间不能比较,就只能存进去,然后打印出来。建议用StringBuffer或StringBuilder。
所以泛型首先能够让我们更快的发现解决问题,让运行问题减少,安全。
其次,它避免了强制转换的麻烦。
import java.util.*; class GenericsDemo2{ public static void main(String[] args){ TreeSet<String> a1 = new TreeSet<String>(new LenComparator()); a1.add("312"); a1.add("sd"); a1.add("sad"); a1.add("12ewr"); for(Iterator<String> it = a1.iterator();it.hasNext();){ String s = it.next(); System.out.println(s); } } } class LenComparator implements Comparator<String>{ public int compare(String s1,String s2){ int num = new Integer(s1.length()).compareTo(new Integer(s2.length())); if(num == 0) return s1.compareTo(s2); return num; } }
Interface Comparator<T>
从它的使用就可以看出<>可以接受一个引用数据类型(注意基础数据类型是不行的)
泛型使用
泛型类:在整个类中都有效,如果被方法调用那么泛型类的对象明确要操作的具体类型后,所有的操作类型就固定了。泛型方法:为了让不同的方法可以操作不同类型,而且类型还不明确,那么可以将泛型定义在方法上。
静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定可以使用泛型方法。
<T>放的位置是返回值前修饰符后
泛型接口:和泛型类作用一样
class GenericsDemo3{ public static void main(String[] args){ new Demo1<String>().print("123"); new Demo1<String>().show(123); new Demo2().print(123); new Demo2().print("123"); new Demo2().show(123); new Demo2().show("123"); new Demo3<String>().print("123"); new Demo3<String>().show(123); new Demo3<String>().method(123); } } //泛型定义在类上 class Demo1<T>{ public void print(T t){ System.out.println(t); } public void show(int t){ System.out.println(t); } } //泛型定义在方法上 class Demo2{ public <T> void print(T t){ System.out.println(t); } public <Q> void show(Q t){ System.out.println(t); } } class Demo3<T>{ public void print(T t){ System.out.println(t); } public <Q> void show(Q t){ System.out.println(t); } //静态得先加载 所以不能访问类上的泛型T public static <W> void 4000 method(W w){ System.out.println(w); } } //泛型定义在接口上 interface inte<T>{ void show(T t); } class inteimpl<T> implements inte<T>{ public void show(T t){ System.out.println("show:"+t); } }
泛型中的符号
泛型中<E> <T>代表Element和Type
泛型中还有一个通配符/占位符
?表示在不能明确数据类型的情况下表示
import java.util.*; class GenericsDemo5{ public static void main(String[] args){ ArrayList<String> a1 = new ArrayList<String>(); ArrayList<Integer> a2 = new ArrayList<Integer>(); a1.add("aa11"); a1.add("aa12"); a1.add("aa13"); a2.add(11); a2.add(12); a2.add(3); print(a1); // print(a2); } public static void print(ArrayList<String> a1){ for (Iterator<String> it = a1.iterator();it.hasNext() ; ) { System.out.println(it.next().length()); } } public static void print(ArrayList<?> a1){ for (Iterator<?> it = a1.iterator();it.hasNext() ; ) { System.out.println(it.next()); } } public static <T> void print2(ArrayList<T> a1){ for (Iterator<T> it = a1.iterator();it.hasNext() ; ) { T t = it.next(); try{ System.out.println(t instanceof String); }catch(Exception e){} } } }
泛型属于多态的一种表现形式,所以它也不能预先使用子类其特有的方法。(函数重载、继承/方法重写、运算符重载等一样)
泛型的限定
泛型的限定是为了限定泛型,扩展。<? extends E>可以接受E类型或E的子类型,上限。
<? super E>可以接受E类型或E的父类型,下限。