黑马程序员_泛型之学习笔记

来源:互联网 发布:3dmax建模算法 编辑:程序博客网 时间:2024/05/21 21:38

------- android培训、java培训、期待与您交流! ---------- 

泛型的引出

 

在程序中定义了一个

ArrayList al =new ArrayList();

Al.add(“123”);

Al.add(1);

 

使用iterator进行遍历的时候

 

需要强转对象后,才能使用其对象特有的方法,由于next返回 一个object

Iterator it=al.iterator();

比如String s = (String) it.next;

System.out.println(s.length());

 

当迭代到1的时候,就会出现问题 。但是在编译的时候发现不了这个问题。

原因是arraylist存入不同类型元素到导致的。

 

所以jdk1.5版本后出现了泛型这个新特性。解决了安全问题。

 

好处

1:将运行时期出现的问题ClassCastException,转移到了编译时期,

方便程序员解决问题,让运行时期问题减少。

 

2:避免了强制转换麻烦。

 

其实泛型就是将一个本来不确定类型,使用强制类型的方式来处理数据。

定义一个泛型集合

ArrayList<String>al = new ArrayList<String>();

//泛型也就是将一个本来不确定的类型的容器使之成为一个指定的类型的容器。

//也就是这个集合中只能存储String类型的对象。

 Al.add(1);//系统就会在编译时候报错

这时

 

使用al.iterator()将数据(String)取入迭代器中。所以迭代器中也要指明存入元素的类型

 

所以,在Iterator定义的时候

Iterator <String>it = al.iterator();

 

使用 it.next();的到的对象就是指定的类型了,不用强转了。

 

泛型的格式:通过<>来定义要操作的引用数据类型。

在使用java提供的对象时候,什么时候写泛型呢?

通常在集合框架中很常见,只要见到<>就要定义泛型。

 

比如:在定义几个集合的时候,使用了泛型,就是指定了集合所要操作的数据类型。

在集合中的方法也是操作的具体类型的对象。

 

其实对于<>来说,就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 

其实也就是一个参数类型的变量,可以动态指定一个变量的类型。

 

 

 

在定义一个TreeSet集合时候,如果我们指定了其中存入的元素为String

TreeSet<String>ts = new TreeSet<String>();

 

当我们想定义一个特殊的比较器时候,如下

classComimplementsComparator

{

    publicintcompare()

    {

      

    }

}

在上边实现接口的时候,我们很自然的就想到了,可以指定这个比较器究竟比较的什么类型的元素,这样就避免了compare中对object进行强转的问题。所以用泛型指定

一个比较器接口,使之明确自己要去比较什么类型的对象

classComimplementsComparator<String>

{

    publicintcompare()

    {

      

    }

}

在对应的compare中也就明确了类型

publicintcompare(Stringsstrings1)

    {

      

    }

 

 

自己理解:

当指定了一个类型的同时,在集合中凡是出现<T>的地方 ,就相当于给T赋值了一个类型。把T指明了一个指定的类型。

 

有了泛型,终于避免了强转。(不安全的方式)

 

学习完集合中,也发现定义一个java类不再是那么的简单了。

 

需要定义equals方法,hashCode方法,-----》为了让hashSet集合类使用。

需要实现Comparable接口,是一个类具有默认的比较性。至于用不用,也需要写上,这样就可以用到各个集合上。

 

需要定义toString()方法,便于集合对象的显示。

 

 

接下来就是,我们可不可以自己定义一个泛型类开发呢?

 

比如

我们使用一个工具类创建一个对象的时候

classWorker

{

}

 

class Tool

{

    privateWorkerw;

 

    publicWorker getW() {

       returnw;

    }

 

    publicvoidsetW(Worker w) {

       this.w = w;

    }

   

}

如果我们需要创建一个学生对象的时候,就还需要创建一个学生工具类,很麻烦。这时就想到了泛型去指定这个Tool中所创建的类型。

classTool<T>//这里定义的类就能指定一个数据的类型,在创建这个类的时候,指定这个//T的类型,从而使类中出现T的地方都转成指定的类型。

{

    private Tw;

 

    public TgetW() {

       returnw;

    }

 

    publicvoidsetW(Tw) {

       this.w =w;

    }

   

}

从而就可以创建一个指定类型的对象了。

上述就是创建一个泛型类的演示。

 

现在就可以使用泛型去创建一个该类的对象了。

 

什么时候需要定义泛型类

 

当类中要操作的引用数据类型不确定的时候,使用一个类型变量去指定其类型(根据传入的参数)。

早期定义object完成扩展,现在定义泛型完成扩展。

 

泛型定义在方法上,也叫泛型方法

 

为什么要定义泛型方法了,由于在定义泛型类的时候,只要明确了类型,在整个类中有效,如果被方法使用,那么泛型类的对象要操作的具体类型后,所有要操作的类型就已经固定了。

为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

 

把泛型定义在方法上其实很简单

packageday2;

importjava.util.*;

publicclassFanxing {

 

   

    publicstaticvoidmain(String[] args)

    {

       newDemo().show("23");

       newDemo().print(new Integer(123));

    }

 

}

 

class Demo

{

    public<T> voidshow(T t)

    {

       System.out.println(t);

    }

    public<Q>void print(Q q)

    {

       System.out.println(q);

    }

}<T>放在返回值类型的前面。

 

在调用时候,传入什么类型的数据,就使用什么类型

 

当一个静态的方法使用泛型类的时候  

我们知道,只有在创建一个对象的时候,才能指定泛型类所定义的类型。

而静态方法不需要创建对象,所以不能使用泛型类传入的类型。

所以与普通方法不同。不可以访问类上定义的泛型

如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

    publicstatic<B>void method(B b)

    {

 

       System.out.println(b);

    }         

要十分主要你究竟是在定义一个泛型类还是在使用一个泛型类去创建一个对象。

这两者这间有很大的区别

泛型的高级应用。

 

我们定义了两个集合

ArrayList<String>al  = new ArrayList<String>();

ArrayList<Integer> al2  = new ArrayList<Integer>();

 

但是不能这样

ArrayList<String> al =new ArrayList<Integer>();

叫做左右两边的类型不匹配。

 

当我们想去打印类型不同的集合中的对象时候,我们可以用一个通配符来表示

 

 

Public static void print(ArrayList<?>al)//这就是你传什么就是什么吧。

//用问号当做一个占位符。

{

   Iterator<?> it = al.iterator();

   System.out.println(it.next);

}

这样就能打印print(al);print(al2)

 

也可以这样使用

Public static <T> voidprint(ArrayList<T> al)//这就是你传什么就是什么吧。

//用问号当做一个占位符。

{

   Iterator<T> it = al.iterator();

   System.out.println(it.next);

}

这样也可以

 

但是这样写可以这样做。T t = it.next();

 

当一个函数的参数既想接收该类型的集合,又想传一个该类型子类型的集合的时候,我们使用

    public static void print(ArrayList<?extends Person> al)

//这就表明了既可以使用Perosn类型的ArrayList也可以是person类型的子类型的arraylist

 

?叫做占位符,也就是泛型定义的类型不明确。

 

extendsE 说明这个位置可以接收E类型或者E的子类型的集合。

 

 

superE 可以接收E类型或者E的父类型

 

要明确这是在创建的时候要传入的类型值。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玻尿酸打鼻子双眼间距好怪怎么办 喝咖啡后胃不舒服想吐怎么办 分期付款买的车不想还款了怎么办 考试时打小抄被同学发现怎么办 生完二胎计生办强制要求上环怎么办 没办二代身份证户口被注销怎么办 川航特价儿童票名字写错怎么办 川航机票名字错一个字怎么办 买飞机票名字打错了一个字怎么办 坐飞机耳朵聋了下飞机还痛怎么办 小孩咳嗽两个月了还不好怎么办 生完小孩肚子瘦不下来怎么办 胆子小一个人在家里都害怕怎么办 怀了双胞胎两个宝宝很挤怎么办 飞机无人陪护如果接机延误该怎么办 过年要坐火车回家 狗狗怎么办 一岁八个月宝宝小腿弯怎么办 2岁宝不愿意坐马桶拉屎怎么办 宝宝两岁多肺炎出院还老咳嗽怎么办 去外国机场买机票不会说外语怎么办 坐飞机不能带的物品办理托运怎么办 深圳外地户口儿童要办身份证怎么办 网上订票错写了护照号怎么办 国航 在智能火车票订飞机票订反了怎么办 办社保卡的时候填错地址怎么办 两个人住酒店只有一张身份证怎么办 农村社保卡信息错了说改不了怎么办 社保卡与原医保卡信息错误怎么办 学校发的社保卡丢了怎么办 魔棒工具选中选区后再怎么办 微信每次打开都出现月球图案怎么办 仙人掌的刺扎手里弄不出来怎么办 保险交满15年领了一年死了怎么办 狗咬了出了点血怎么办 被小狗咬到了吃了海鲜怎么办 想给一个人道歉又不敢说怎么办 被尘封的故事中魔法师不见了怎么办 宝骏5602挡升3挡有点卡怎么办 剥开的榴莲没熟壳又扔了怎么办 视频播放器激活码设备超限了怎么办 ai如何把右边菜单栏隐藏了怎么办