Java集合之泛型
来源:互联网 发布:数据录入员压力大吗 编辑:程序博客网 时间:2024/06/14 20:11
转载自 http://www.cnblogs.com/jbelial/archive/2013/03/30/2990935.html
所谓泛型就是允许在定义类、接口时指定类型形参,这个类型形参将在声明变量、创建对象时确定。增加了泛型支持后的集合,完全可以记住集合中元素的类型,并可以在编译时检查集合中元素的类型。即解决一些安全问题;同时还可以让代码变得更加简洁。
一.使用泛型
泛型的格式:通过<>来定义要操作的引用数据类型。
1 public class GenericDemo { 2 public static void main(String[] args) 3 { 4 // 创建一个只能保存字符串的List 集合 5 List<String> strList = new ArrayList<String>() ; 6 strList.add("Generic") ; 7 // 如果存放其他对象这回出现编译错误。 8 System.out.println(strList); 9 }10 }
使用泛型的好处:
1、将运行时期出现的ClassCastExcpetion , 转移到了编译时期。方便于程序员解决问题,让运行时期问题减少。
2、避免了强制转换的麻烦。
如下代码:
1 class StringDemo 2 { 3 String name ; 4 public StringDemo(String name ) 5 { 6 this.name = name ; 7 } 8 } 9 public class GenericDemo {10 public static void main(String[] args)11 {12 List list = new ArrayList() ; 13 list.add(new StringDemo("烦烦烦烦烦01")) ; 14 list.add(new StringDemo("烦烦烦烦烦02")) ; 15 list.add(new StringDemo("烦烦烦烦烦03")) ; 16 list.add(new StringDemo("烦烦烦烦烦04")) ; 17 18 list.add(1000) ; 19 MyIterator(list) ; 20 }21 // 定义遍历方法:22 public static void MyIterator(List list)23 {24 Iterator it = list.iterator() ; 25 while (it.hasNext() )26 {27 StringDemo s = (StringDemo) it.next() ; 28 System.out.println(s.name);29 }30 }31 }
}
在调用MyIterator(List list) 方法时会发生ClassCastException 异常。而且在编译时是不会有任何提示,只有运行时会出现,所以使的程序存在安全隐患。
如果使用泛型则会在编译时提示错误,而且在遍历时不需要强制转换。如:
1 class StringDemo 2 { 3 String name ; 4 public StringDemo(String name ) 5 { 6 this.name = name ; 7 } 8 } 9 public class GenericDemo {10 public static void main(String[] args)11 {12 List<StringDemo> list = new ArrayList<StringDemo>() ; 13 list.add(new StringDemo("烦烦烦烦烦01")) ; 14 list.add(new StringDemo("烦烦烦烦烦02")) ; 15 list.add(new StringDemo("烦烦烦烦烦03")) ; 16 list.add(new StringDemo("烦烦烦烦烦04")) ; 17 18 // 下面一行代码在编译时会出错:19 list.add(1000) ; 20 MyIterator(list) ; 21 }22 // 定义遍历方法:23 public static void MyIterator(List list)24 {25 Iterator<StringDemo> it = list.iterator() ; 26 while (it.hasNext() )27 { 28 System.out.println( it.next().name);29 }30 }31 }
注意:在使用Java提供的对象时,什么时候写泛型呢?
只要见到<> (<>就是用来接收类型的。),就要定义泛型。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
二.了解泛型
ArrayList<E> 类定义和ArrayList<Integer> 类引用中涉及的术语:
> 整个称为ArrayList<E> 泛型类型。
> ArrayList<E> 中的E称为类型变量或类型参数。
> 整个ArrayList<Integer> 称为参数化的类型。
> ArrayList<Integer> 中的Integer 称为类型参数的实例或实际类型参数。
> ArrayList<Integer> 中的<> 念着typeof
> ArrayList 称为原始类型
参数化类型不考虑类型参数的继承:
> Vector<String> v = new Vector<Object>() ; //错误
> Vector<Object> v = new Vector<String>() ; //也错误
创建数组实例时,数组的元素不能使用参数化的类型:
> Vector<Integer> vectorList[] = new Vector<Integer>[10] ; //错误
三.定义泛型类
除了Java提供了一些类增加了泛型支持外,我们可以定义泛型支持的类。那么在什么时候定义泛型类呢?
当类中操作的引用数据类型不确定时可以定义泛型类。
格式如下:
class Tools<T>{}
具体操作:
1 //定义一个工具类Tools 2 //因为不知道要操作的类型是什么所增加泛型支持 3 class Tools<T> 4 { 5 // 包含输出函数: 6 public void sop(T t) 7 { 8 System.out.println("sop:"+t); 9 } 10 }11 //定义一个Books 类12 class Books13 {14 private String name ;15 public Books(String name)16 {17 this.name = name ; 18 } 19 // 重写toString 方法20 public String toString()21 {22 return "name = " + name ; 23 }24 }25 public class GenericText 26 {27 public static void main(String[] args)28 { 29 // 创建一个Tools 实例tool ,定义 tool 要操作的数据类型为Books 30 Tools<Books> tool = new Tools<Books>() ; 31 // tool 可以操作 Books 类型,还可以操作Integer 类型和String类型。32 tool.sop(new Books("诛仙")); 33 }34 }
定义一个Tools 类 用来完成打印操作,但是应为不知道要操作的数据类型是什么,所以可以定义成泛型类。
三.泛型方法
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,
那么可以将泛型定义在方法上。
定义泛型方法格式如下:
public <T> void show(T t) 注意:<>放在修饰符后面,返回值前面 { }
具体操作如下:
1 //定义一个工具类Tools 2 //因为不知道要操作的类型是什么所增加泛型支持 3 class Tools<T> 4 { 5 // 包含输出函数: 6 public void sop(T t) 7 { 8 System.out.println("sop:"+t); 9 } 10 // 定义的泛型方法:11 public <T> void show (T t)12 {13 System.out.println("show:"+t);14 }15 }16 //定义一个Books 类17 class Books18 {19 private String name ;20 public Books(String name)21 {22 this.name = name ; 23 } 24 // 重写toString 方法25 public String toString()26 {27 return "name = " + name ; 28 }29 }30 public class GenericText 31 {32 public static void main(String[] args)33 { 34 // 创建一个Tools 实例tool ,定义 tool 要操作的数据类型为Books 35 Tools<Books> tool = new Tools<Books>() ; 36 // tool 可以操作 Books 类型,还可以操作Integer 类型和String类型。37 tool.sop(new Books("诛仙")); 38 tool.show(new Books("诛仙")) ; 39 // 下面的方法编译时会报错》、:40 tool.sop(1000) ;41 tool.sop("String") ;42 43 // 但下面却不会报错,并且正常运行。44 tool.show(1000) ; 45 tool.show("String") ;46 }47 }
通过上面的代码,可以知道泛型类和泛型方法可以同时定义,且不冲突。但是也有特殊情况:静态方法不可以访问定义类上的泛型,如:
class Tools<T> { public static void method(T t) { } } 上面的书写是错误的,
如果静态方法操作的引用数据类型不确定,可将泛型定义在方法上:
class Tools<T> { public static <T> void method(T t) { } }
四.泛型限定和通配符
4.1 通配符
类型通配符是一个问号(?):问号作为类型实参传给List 集合写作:List<?>。
1 //定义一个Books 类 2 class Books 3 { 4 private String name ; 5 public Books(String name) 6 { 7 this.name = name ; 8 } 9 // 重写toString 方法10 public String toString()11 {12 return "name = " + name ; 13 }14 }15 public class GenericText 16 {17 public static void main(String[] args)18 {19 // 创建一个只能存储 Books 类型元素的 List 集合。20 List<Books> bookList = new ArrayList<Books>() ; 21 bookList.add(new Books("诛仙")) ;22 bookList.add(new Books("笑傲江湖")) ; 23 24 // 创建一个只能存储String 类型元素的List 集合25 List<String> strList = new ArrayList<String>() ;26 strList.add("Generic001") ;27 strList.add("Generic002") ;28 29 MyIterator(strList) ; 30 MyIterator(bookList) ;31 32 }33 // 定义个遍历List 集合的方法。34 public static void MyIterator(List<?> strList)35 {36 Iterator<?> it = strList.iterator() ;37 while(it.hasNext())38 {39 System.out.println(it.next());40 }41 }42 }
在 MyIterator 方法中使用了类型通配符 ? ,好处是只写一个 遍历方法便可操作List 集合的遍历,缺点是不能调用元素中的特定方法。
4.2 泛型限定:
1、 ? extends E : 可以接收E类型或者E的子类型。上限定。
2、? super E : 可以接收E类型或者E的父类型。下限定。
1 class Books 2 { 3 String name ; 4 public Books(String name) 5 { 6 this.name = name ; 7 } 8 public String toString() 9 {10 return "name:" + name ; 11 }12 }13 class ComicBooks extends Books14 { 15 public ComicBooks(String name) {16 super(name); 17 } 18 }19 class Person_1 20 {21 String name ; 22 public Person_1 (String name)23 {24 this.name = name ;25 }26 }27 public class GenericTreeSet {28 29 public static void main(String[] args)30 {31 // 定义 TreeSet 集合 ,并且里面只存储ComicBooks类型元素,切按照自已的比较规则排序32 TreeSet<ComicBooks> bookTree = new TreeSet<ComicBooks>(new MyComparable()) ;33 34 bookTree.add(new ComicBooks("aaaaaa")) ;35 bookTree.add(new ComicBooks("aaa3gfaaa")) ;36 bookTree.add(new ComicBooks("afdfef")) ;37 bookTree.add(new ComicBooks("asdffefq")) ;38 // 调用39 MyIterator(bookTree) ; 40 41 // 下面代码编译会出现异常42 TreeSet<Person_1> p = new TreeSet<Person_1>(new MyComparable()) ;43 }44 // 定义遍历方法:只能操作Books 类型或者 Books的子类型45 public static void MyIterator(TreeSet<? extends Books> bookTree)46 {47 Iterator<? extends Books> it = bookTree.iterator() ;48 while(it.hasNext())49 {50 System.out.println(it.next().toString());51 }52 }53 }54 //定义比较器 :按倒序排序且该比较器只适用于 Books 类型或者 Books的子类型55 class MyComparable implements Comparator<Books>56 { 57 public int compare(Books o1 , Books o2)58 { 59 return o2.name.compareTo(o1.name);60 } 61 }
所以,当我们定义的某些方法只作用与某些类与其子类时,可以通过泛型限定来实现。
- Java集合之泛型
- java基础之泛型和集合
- java集合框架之泛型
- 集合之泛型
- Java集合之Set集合
- java集合之集合简介
- Java集合之集合框架
- Java集合之-Map集合
- Java集合之Set集合
- Java集合之List集合
- java泛型集合
- JAVA泛型集合
- Java集合框架(三)之泛型详解
- 每天一读之 < Java 泛型与集合框架 >
- 黑马程序员 java基础 集合框架之泛型
- Java反射机制之集合泛型的本质
- JavaSE入门学习40:Java集合框架之泛型
- JavaSE入门学习40:Java集合框架之泛型
- Python-Day04-装饰器(1)
- Cg Programming/Unity/Diffuse Reflection漫反射
- 第一次写博客
- 递归SQL简单学习
- 大白菜装机步骤
- Java集合之泛型
- activity启动流程记录
- AGC 018
- MUI介绍
- FPGA基础知识之1——FPGA是什么?
- Java关键字finally_动力节点Java学院整理
- 在 Windows 上安装 MySQL
- 蓝牙HCI剖析(三)
- jdk配置环境变量