一.
现在借助一个示例,将涉及的泛型内容说一下。
例子里面无非就是一个集合和迭代器。
list里面大概都是这样的,无非是一个迭代器和一个集合。我们讲一个更多一点的,hashset没有必要多说了,意义不太大,和这个是一样的。有一个是不一样的,
就是treeset,它里面带着比较器,带着比较功能。
接着演示,还是泛型。存储一些自定义对象,这就意味着要搞第二个包,这个包里面可以通过快捷操作三个东西,set和get属性的函数,空参数函数,还有this.name=person.name。
在搞treeset时,不能按下图这么写法,
其实一点错也没有,泛型这个技术日后开发必须往上写。5.0就出现了,而且是安全机制,不写不行,必须要写。
写完了,往回加泛型烂透了。应该在使用容器的时候,就明确往容器里面装什么类型的元素。这就和写数组一样,立刻就明确里面放置了什么类型数据。
(现在讲述的就是基于泛型这个新知识点上,对集合的一些操作)
迭代器后面有尖括号,为什么会有尖括号?API中注释了,如上图所示,后面要有尖括号传递参数。如果不这么写,行不行?可以,兼容老版本,1.4没有这个。但是如果用1.5的编辑器,会有注意提示,会有黄色的小灯。
编译没有问题,有人说不用强转了,
没问题,我们就不转了。现在运行一下,看问题在哪儿。这个问题我们见过,
结果提示17行出现了问题,但是我们看没有问题。我们知道treeset是二叉树,它要排序,进行比较。它是怎么比较的呢?有人说,按照年龄比的。凭什么?
为什么不按照姓名比。没把条件告诉人家,怎么比啊?换句话说,person都不具备比价性。得所属comparable这个接口,才有比较性。
上图是早期的写法,先实现接口,然后在内容中添加compareto方法。再次运行,结果如下所示,
怎么修改呢?我们可以调用它的getname和getage,有的人说toString不就完了么,toString只能打印person对象这个字符串,这里有默认字符串。
如果你说我就要姓名,不要年龄,那还是用getname;如果你就要默认字符串,也没什么可以说的。
修改完之后,再看结果就可以了。
结果中进行了简单的排序,四个元素排出来三个。
回过头来看,在实现的那一步,有一个小叹号。我们不想出现出现这个,修改一下语句。添加类型给comparable。改
这里不能添加object,一会儿说明一下为什么不能这么弄。
现在要比价谁,是person。我们可以指定。指定object不行么?指定object的话,还要转,没什么劲。
改为person,下面也要跟着改为person,有人问,为什么?
API接口中,标明了comparable后面定义了泛型。任何对象想要具备比较功能,都要实现这个接口,接口是用于对象比较。我要比较哪个对象呢?
由你来指定,你不指定,这个方法里面就是object,得强转。这里面的T就是,你指定什么,我们就比较什么。
在接口中写完person后,黄色叹号就没有了。同时,下面的方法中,也要改为person,但是具体的写法如下。
这是泛型的好处。
有人说之前comparable后面接的是E,这里怎么变成T了呢?无论是E还是T,都是参数变量名。它用于接收一个类型,传递进来什么,T就代表什么,就是变量名。有人说,为什么写T?这是某一个单词的简写,type。
说一个比较疑惑的问题,有人说,准备覆盖equals方法。通过快捷方法调用出来的方法,参数就是object,这里不能改成person。
这个方法来自于object,object里面没有定义过泛型,这块是固定类型object。
完整的写法比较复杂,先要判断,再要强壮。判断两个对象是否相同,然后再判断类型是否合适。
但是这么写还不够专业,out+shift+s,每个对象都要建立判断相同的依据。快捷方式中已经全部定义好了,
它已经替我们写完了,它的代码和之前我们自己写的差不多。只不过31固定值变成了final。equals更夸张,判断什么的,写的更多。
如果不自己写的话,使用系统的也是可以的。
到这里就将泛型和相关的方法提了一下,叫做比较方法。有人说,自己更喜欢。对于下面的例子是按年龄来的,要是改成姓名排怎么办。
采用比较器,讲一讲比较器。utill包里面的comparator。有人说,接口里面有两个方法,为什么这里就实现了一个呢?都是抽象的。为什么不用实现呢?
因为本身就继承object,就替换这个方法了,已经覆写完了。
顺便说一下,为什么比较器中有equals方法,它是是在判断比较器是否相同。两个比较器也能判断,但是我们一般判断不多,所以不去覆写它。
用object里面默认的方法就行了。
修改之后的结果如下所示。对于源程序,要加上比较器。
把涉及到泛型的地方都给大家演示一下,会发现,泛型就在集合框架当中,应用是最多的,因为容器不能明确里面装的是什么类型对象。
这个时候,就用泛型来表示,你指定什么类型,我就往里面存或者取什么类型。
一个问题,写泛型的时候,能不能写成<int>呢?不能,因为泛型里面不可能写基本数据类型的。写成<int[ ]>是可以的,只要是引用数据类型都可以。
有人说,书写的就是ts.add(4),那里面写成什么类型?写成Integer就可以了。
引用数据类型不确定的时候,采用泛型表示。