Java开发笔记(六十九)泛型类的定义及其运用
前面从泛型方法的用法介绍到了泛型的起源,既然单个方法允许拥有泛化的参数类型,那么一个类也应当支持类级别的泛化类型,例如各种容器类型ArrayList、HashMap等等。一旦某个类的定义代码在类名称后面添加“<T>”这种泛型声明,该类就变成了泛型类(也称模板类)。况且泛型类不单单支持一种泛型参数,还支持同时声明多种泛型参数,像“<T>”表示当前类存在唯一一种泛型参数;若想声明当前类拥有两种泛型参数,则可使用“<T, R>”这种以逗号隔开的泛型列表;同时声明三种泛型参数的话,尖括号内的泛型列表就有三个参数,形如“<U, V, W>”这般;至于更多种泛型参数的声明方式可依此类推。
在泛型类的内部代码中,事先已经声明的泛型可以拿来直接使用,无需在成员方法前面额外添加“<T>”。除此之外,在类代码中使用泛型T就跟使用普通类型一样,可以用它来创建泛型实例,可以用它表示输入参数的类型,也可以用它表示输出参数的类型。举个泛型类的简单应用例子,现在准备利用清单List来保存数据,然后想获取这组数据当中最长的元素,以及最短的元素。按照前述需求,划分该泛型类应当具备的功能,初步罗列包括以下几点:
1、泛型类要声明一个泛型参数“<T>”,用于给清单需要的元素类型占位;
2、定义泛型类的构造方法,传入待保存的清单对象,其中对象类型为“List<T>”;
3、定义getMaxLengthItem方法,用于获取长度最大的清单元素,注意该方法的输出参数类型为T;
4、定义getMinLengthItem方法,用于获取长度最小的清单元素,该方法的输出参数类型也为T;
根据上面的几点功能要求,编码实现的泛型类代码示例如下:
//定义简单的泛型清单。
//类名后面添加“<T>”,表示该类的内部代码中,所有的T类型都为外部需要时再指定的泛型。
//如果泛型不止一个,则用逗号隔开,比如两个泛型可用“<T, R>”。
public class SimpleList<T> {
private List<T> list; // 清单。注意清单元素的数据类型为泛型T // 构造方法,传入要保存的清单数据
public SimpleList(List<T> list) {
this.list = list;
} // 获取当前保存的清单数据
public List<T> getData() {
return this.list;
} // 获取长度最大的清单元素。注意这里的返回数据为泛型T
public T getMaxLengthItem() {
if (list == null || list.size() <= 0) {
return null;
}
T t = list.get(0); // 利用T声明了一个泛型变量t
for (int i = 0; i < list.size(); i++) {
if (list.get(i).toString().length() > t.toString().length()) {
t = list.get(i);
}
}
return t;
} // 获取长度最短的清单元素。注意这里的返回数据为泛型T
public T getMinLengthItem() {
if (list == null || list.size() <= 0) {
return null;
}
T t = list.get(0); // 利用T声明了一个泛型变量t
for (int i = 0; i < list.size(); i++) {
if (list.get(i).toString().length() < t.toString().length()) {
t = list.get(i);
}
}
return t;
}
}
从这个泛型类的代码可知,泛型T犹如系统自带的数据类型一般,它在泛型类内部的使用毫无障碍,你可以把它想象为Integer类型,或者Double类型。纵观整个泛型类的代码,唯有最开始的类名后面多了个“<T>”,其它地方跟普通类就没什么两样了。
外部调用泛型类的时候,可参照ArrayList、HashMap等容器类的用法,同样在类名后面添加形如“<具体的数据类型名称>”的模板。下面是段SimpleList的测试代码,先构造指定清单的泛型实例,再分别调用getMaxLengthItem与getMinLengthItem方法获取最长的元素和最短的元素,完整代码如下所示:
// 数组工具Arrays的asList方法可以把一系列元素直接赋值给清单对象
List<Double> doubleList = Arrays.asList(1.1, 2D, 3.1415926, 11.11);
// 泛型实例的参数类型跟在类名称后面,以尖括号包裹
SimpleList<Double> simpleList = new SimpleList<Double>(doubleList);
// 打印清单中最长的元素
System.out.println("simpleList.getMaxLengthItem()=" + simpleList.getMaxLengthItem());
// 打印清单中最短的元素
System.out.println("simpleList.getMinLengthItem()=" + simpleList.getMinLengthItem());
运行以上的测试代码,观察到下面的日志结果,可见泛型类SimpleList正确挑选出了最长的元素和最短的元素:
simpleList.getMaxLengthItem()=3.1415926
simpleList.getMinLengthItem()=1.1
更多Java技术文章参见《Java开发笔记(序)章节目录》
Java开发笔记(六十九)泛型类的定义及其运用的更多相关文章
- Java开发笔记(十九)规律变化的for循环
前面介绍while循环时,有个名叫year的整型变量频繁出现,并且它是控制循环进出的关键要素.不管哪一种while写法,都存在三处与year有关的操作,分别是“year = 0”.“year<l ...
- Java开发笔记(九十九)定时器与定时任务
前面介绍了线程的几种运行方式,不管哪种方式,一旦调用了线程实例的start方法,都会立即启动线程的事务处理.然而某些业务场景在事务执行时间方面有特殊需求,例如期望延迟若干时间之后才开始事务运行,又如期 ...
- Java开发笔记(十六)非此即彼的条件分支
前面花了大量篇幅介绍布尔类型及相应的关系运算和逻辑运算,那可不仅仅是为了求真值或假值,更是为了通过布尔值控制流程的走向.在现实生活中,常常需要在岔路口抉择走去何方,往南还是往北,向东还是向西?在Jav ...
- .Net开发笔记(十九) 创建一个可以可视化设计的对象
阅读本篇博客之前需要了解VS窗体设计器的工作原理,详细可参见本系列博客(十).(十一).(十二).必须需要知道的一条结论就是:处于窗体设计器(Form Designer)中的任何组件(包含控件,下同) ...
- Java学习笔记(十九)——Java 日志记录 AND log4j
[前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...
- 【Java学习笔记之十九】super在Java继承中的用法小结
1)有人写了个很好的初始化属性的构造函数,而你仅仅想要在其中添加另一些自己新建属性的初始化,这样在一个构造函数中调用另外一个构造函数,可以避免重复的代码量,减少工作量: 2)在一个构造函数中调用另外一 ...
- Java开发笔记(十)一元运算符的技巧
前面讲到赋值运算符的时候,提到“x = x+7”可以被“x += 7”所取代,当然Java编程中给某个变量自加7并不常见,常见的是给某变量自加1,就像走台阶,一般都是一级一级台阶地走,犯不着一下子跳上 ...
- Java开发笔记(十二)布尔变量论道与或非
在编程语言的设计之初,它们除了可以进行数学计算,还常常用于逻辑推理和条件判断.为了实现逻辑判断的功能,Java引入了一种布尔类型boolean,用来表示“真”和“假”.该类型的变量只允许两个取值,即t ...
- Java开发笔记(十四)几种运算符的优先级顺序
到目前为止,我们已经学习了Java语言的好几种运算符,包括算术运算符.赋值运算符.逻辑运算符.关系运算符等基础运算符,并且在书写赋值语句时都没添加圆括号,显然是默认了先完成算术.逻辑.关系等运算,最后 ...
- Java开发笔记(十五)短路逻辑运算的优势
前面提到逻辑运算只能操作布尔变量,这其实是不严谨的,因为经过Java编程实现,会发现“&”.“|”.“^”这几个逻辑符号竟然可以对数字进行运算.譬如下面的代码就直接对数字分别开展了“与”.“或 ...
随机推荐
- OJ002
register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率.注意是尽可能,不是绝对. 因为,如果定义了很多register变量,可能会超过CPU的寄 ...
- Centos7-驱动小米WIFI做AP
参考文章: http://blog.csdn.net/sumang_87/article/details/38168877 http://blog.csdn.net/hktkfly6/article/ ...
- 【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- [Swift]LeetCode848. 字母移位 | Shifting Letters
We have a string S of lowercase letters, and an integer array shifts. Call the shift of a letter, th ...
- Python档案袋( 面向对象 )
类即是一个模型,根据模型建立起不同的对象,对象间拥有共同的一些属性 简单的类: class P: #类变量,所有实例共享变量,推荐使用方法是:类名.类变量名 pvarx="ppvar1&qu ...
- python编程实战
1.计算对称平方数 题目描述 打印所有不超过n(n<256)的,其平方具有对称性质的数,如11*11=121. 输入描述 无 输出描述 每行一个数,表示对称平方数 def f(n): flag ...
- python判断文件是否存在
# 判断文件是否存在 def judgejson(jsonpath): # 如果存在就返回True,不存在就返回False return os.path.exists(jsonpath)
- BBS论坛(十三)
13.1点击更换图形验证码 (1)front/signup.html <div class="form-group"> <div class="inpu ...
- 【从零开始自制CPU之学习篇06】寄存器
上一篇文章学习了总线的相关知识,途中ABC当时假设为一个个的8位寄存器.这一篇要学习怎么构建这个寄存器. 这分为两个三个部分,数据输入,寄存器,数据输出.首先不管输出,来看数据输入和寄存器这两个部分. ...
- IdentityServer4之Resource Owner Password Credentials(资源拥有者密码凭据许可)
IdentityServer4之Resource Owner Password Credentials(资源拥有者密码凭据许可) 参考 官方文档:2_resource_owner_passwords ...