Java集合框架(三)之泛型详解
来源:互联网 发布:淘宝客源码下载 编辑:程序博客网 时间:2024/04/28 11:08
泛型(Generics)
什么是泛型?泛型是在jdk1.5以后出现的新特性,用于解决安全问题,是一个类型安全机制。
泛型格式:通过<>来定义要操作的引用数据类型。
例如以下的例子:
import java.util.*;
class GenericsDemo
{
publicstatic void main(String[] args)
{
ArrayList<String> list=new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
list.add("huangsan");
//list.add(newInteger(3));//会出编译时错误
for(Iterator<String>it=list.iterator();it.hasNext();){
Strings=it.next();
System.out.println(s);
}
}
}
我们可以看到使用泛型有很多好处。
a) 将运行时期出现问题ClassCastException,转移到了编译时期。方便程序员解决问题。让运行时期问题减少,安全。
b) 避免了强制转换的麻烦。
什么时候使用泛型呢?是在使用java提供的API的一些对象时,只要见到<>就要定义泛型,通常在集合框架中很常见。<>就是用来接受类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
自定义泛型
自定义泛型类
自定义泛型有什么好处呢?自定义泛型最大的好处就是扩展性好。我们看看如下的例子:
class GenericsTool<T>
{
privateT t;
publicT getObject(){
returnt;
}
publicvoid setObject(T t){
this.t=t;
}
}
class CustomGenericsDemo
{
publicstatic void main(String[] args)
{
/*
Objcet
*/
ObjectToolot=new ObjectTool();
ot.setObject(newStudent());
Studentstu=(Student)ot.getObject();
/*
Generics,T也可以是Student
*/
GenericsTool<Person>gt=new GenericsTool<Person>();
gt.setObject(newPerson());
Personp=gt.getObject();//不需要强制转换
}
}
我们可以看出自定义泛型的可扩展性高。
我们什么时候自定义泛型类呢?当类中要操作的引用数据类型不确定时候,我们在jdk1.5前是个使用Object来完成扩展,现在呢我们使用泛型来完成扩展。
自定义泛型方法
我们要注意,泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所要操作的类型就固定的了。就是说我们在泛型类里传入的类型是什么类型,它的泛型方法就是什么类型。这也是泛型类的一个局限性。
那么为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。就是说泛型就只能在方法里有效,在调用方法时,可以任意传入不同类型对象。
例如:
class MethodGenericsDemo
{
publicstatic void main(String[] args)
{
MethodGenericsDemomd=new MethodGenericsDemo();
/*
可以传入任何类型
*/
md.show("haha");
md.show(3);
md.show(true);
}
public<T> void show(T t){ //泛型方法
System.out.println(t);
}
}
静态方法泛型:我们注意静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
静态方法格式:public static <T> void method(){};
自定义泛型接口
泛型自定义在接口是怎样的呢?
interface Generics<T>
{
publicvoid show(T t);
}
/*
第一种实现泛型接口类
*/
class InGenerics_1 implementsGenerics<String>
{
publicvoid show(String s){
System.out.println(s);
}
}
/*
第二种实现泛型接口类
*/
class InGenerics_2<T> implementsGenerics<T>
{
publicvoid show(T t){
System.out.println(t);
}
}
class InterfaceGenericsDemo
{
publicstatic void main(String[] args)
{
InGenerics_1ig1=new InGenerics_1();
ig1.show("haha");
InGenerics_2<Integer>ig2=new InGenerics_2<Integer>();
ig2.show(4);
}
}
泛型限定(Generics Qualify)
什么是泛型限定呢?泛型限定是使用?通配符,也可以理解为占位符,是用来表示不确定的类型。格式:<?>
泛型总共有两种限定:
a) 上限:<? extendsE>,可以接收E类型或者是E类型的子类
b) 下限:<?super E>,可以接受E类型或者E的父类型。通常用的不多。
如以下关于上限的例子:
import java.util.*;
class UpGenericsQualifyDemo
{
publicstatic void main(String[] args)
{
ArrayListlist1=new ArrayList();
list1.add(newPerson("zhangsan"));
list1.add(newPerson("lisi"));
list1.add(newPerson("wangwu"));
println(list1);
System.out.println("-----------------------");
ArrayListlist2=new ArrayList();
list2.add(newStudent("zhangsan_1"));
list2.add(newStudent("lisi_1"));
list2.add(newStudent("wangwu_1"));
println(list2);
}
publicstatic void println(ArrayList<?extends Person> list){
for(Iterator<? extends Person>it=list.iterator();it.hasNext();){
System.out.println(it.next().getName());
}
}
}
class Person
{
privateString name;
Person(Stringname){
this.name=name;
}
publicString getName(){
returnname;
}
}
class Student extends Person
{
Student(Stringname){
super(name);
}
}
我们知道集合类中TreeSet的一个Comparator接口的定义是publicComparator<? superE>comparator()这样定义的,这个就是所谓的下限。现在我们就这个举下例子:
import java.util.*;
class DownGenericsQualifyDemo
{
publicstatic void main(String[] args)
{
TreeSetsset=new TreeSet(new MyCom());
sset.add(newStudent("sa3"));
sset.add(newStudent("sa1"));
sset.add(newStudent("sa5"));
sset.add(newStudent("sa2"));
for(Iterator it=sset.iterator();it.hasNext();){
System.out.println(it.next());
}
System.out.println("---------------");
TreeSetwset=new TreeSet(new MyCom());
wset.add(newStudent("wa3"));
wset.add(newStudent("wa1"));
wset.add(newStudent("wa5"));
wset.add(newStudent("wa2"));
for(Iterator it=wset.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
class Person
{
privateString name;
Person(Stringname){
this.name=name;
}
publicString getName(){
returnname;
}
public String toString(){
return"name:"+name;
}
}
class Student extends Person
{
Student(Stringname){
super(name);
}
}
class Worker extends Person
{
Worker(Stringname){
super(name);
}
}
class MyCom implements Comparator<Person> //传一个父类型
{
public int compare(Personp1,Person p2){
return(p1.getName()).compareTo(p2.getName());
}
}
我们看到,我们使用了泛型中的下限,我们就创建了一个自定义比较器comparator。
- Java集合框架(三)之泛型详解
- Java基础之集合框架详解(三)Set篇
- java集合框架详解(三)、List接口
- Java:集合框架(三)Set详解及代码示例
- 黑马程序员——Java之集合框架(三)
- 菜鸟猿大战Java之集合框架系列(三)
- Java之三大集合框架
- JAVA面试之集合框架(三)
- Java集合框架(二)之Set详解
- Java集合框架(四)之Map详解
- Java基础之集合框架详解(一)
- Java基础之集合框架详解(二)List篇
- Java集合框架(一)之List详解
- JAVA常用集合框架用法详解基础篇三之Colletion子接口Set
- java集合框架之泛型
- Java集合框架(三)
- Java集合框架(三)
- Java 集合框架三
- android自定义EditText
- android 验证码
- 【WinSocket】WinSocket 之TCP示例
- jQuery的绑定事件
- 图片上传插件,基于jquery的上传插件,ajax图片上传,再更新
- Java集合框架(三)之泛型详解
- 适配器模式
- android 字符串转json
- C中的库函数汇总
- 怎样以少于1000行代码写一个视频播放器-将电影文件中的视频帧存储为BMP图片
- Jmockit入门
- 如何设置root用户密码
- android 图片转为base64
- 基本开发环境配置