Java学习_泛型
- 什么是泛型。
- Java标准库提供的
ArrayList内部就是一个Object[]数组,配合存储一个当前分配的长度,就可以充当“可变数组”。public class ArrayList {
private Object[] array;
private int size;
public void add(Object e) {...}
public void remove(int index) {...}
public Object get(int index) {...}
} 如果用上述
ArrayList存储String类型,会有这么几个缺点:需要强制转型;
不方便,易出错。
- 代码必须这么写:
ArrayList list = new ArrayList();
list.add("Hello");
// 获取到Object,必须强制转型为String:
String first = (String) list.get(0);很容易出现ClassCastException,因为容易“误转型”。
list.add(new Integer(123));
// ERROR: ClassCastException:
String second = (String) list.get(1);要解决上述问题,我们可以为
String单独编写一种ArrayList。public class StringArrayList {
private String[] array;
private int size;
public void add(String e) {...}
public void remove(int index) {...}
public String get(int index) {...}
}这样一来,存入的必须是
String,取出的也一定是String,不需要强制转型,因为编译器会强制检查放入的类型。StringArrayList list = new StringArrayList();
list.add("Hello");
String first = list.get(0);
// 编译错误: 不允许放入非String类型:
list.add(new Integer(123));问题暂时解决。然而,新的问题是,如果要存储
Integer,还需要为Integer单独编写一种ArrayList。实际上,还需要为其他所有class单独编写一种ArrayList。这是不可能的,JDK的class就有上千个,而且它还不知道其他人编写的class。
为了解决新的问题,我们必须把
ArrayList变成一种模板:ArrayList<T>public class ArrayList<T> {
private T[] array;
private int size;
public void add(T e) {...}
public void remove(int index) {...}
public T get(int index) {...}
}T可以是任何class。这样一来,我们就实现了:编写一次模版,可以创建任意类型的ArrayList。// 创建可以存储String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 创建可以存储Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 创建可以存储Person的ArrayList:
ArrayList<Person> personList = new ArrayList<Person>();这样一来,既实现了编写一次,万能匹配,又通过编译器保证了类型安全:这就是泛型。
向上转型
- 在Java标准库中的
ArrayList<T>实现了List<T>接口,它可以向上转型为List<T>。public class ArrayList<T> implements List<T> {
...
} List<String> list = new ArrayList<String>();类型
ArrayList<T>可以向上转型为List<T>。不能把ArrayList<Integer>向上转型为ArrayList<Number>或List<Number>。ArrayList<Integer>和ArrayList<Number>两者完全没有继承关系。
- Java标准库提供的
使用泛型
使用
ArrayList时,如果不定义泛型类型时,泛型类型实际上就是Object编译器如果能自动推断出泛型类型,就可以省略后面的泛型类型。// 可以省略后面的Number,编译器可以自动推断泛型类型:
List<Number> list = new ArrayList<>();泛型接口
除了
ArrayList<T>使用了泛型,还可以在接口中使用泛型。例如,Arrays.sort(Object[])可以对任意数组进行排序,但待排序的元素必须实现Comparable<T>这个泛型接口。public interface Comparable<T> {
/**
* 返回负数: 当前实例比参数o小
* 返回0: 当前实例与参数o相等
* 返回正数: 当前实例比参数o大
*/
int compareTo(T o);
}可以直接对
String数组进行排序。// sort
import java.util.Arrays; public class Main {
public static void main(String[] args) {
String[] ss = new String[] { "Orange", "Apple", "Pear" };
Arrays.sort(ss);
System.out.println(Arrays.toString(ss));
}
}这是因为
String本身已经实现了Comparable<String>接口。如果换成我们自定义的Person类型试试。1 // sort
2 import java.util.Arrays;
3
4 public class Main {
5 public static void main(String[] args) {
6 Person[] ps = new Person[] {
7 new Person("Bob", 61),
8 new Person("Alice", 88),
9 new Person("Lily", 75),
10 };
11 Arrays.sort(ps);
12 System.out.println(Arrays.toString(ps));
13
14 }
15 }
16
17 class Person {
18 String name;
19 int score;
20 Person(String name, int score) {
21 this.name = name;
22 this.score = score;
23 }
24 public String toString() {
25 return this.name + "," + this.score;
26 }
27 }运行程序,我们会得到
ClassCastException,即无法将Person转型为Comparable。我们修改代码,让Person实现Comparable<T>接口。1 // sort
2 import java.util.Arrays;
3
4 public class Main {
5 public static void main(String[] args) {
6 Person[] ps = new Person[] {
7 new Person("Bob", 61),
8 new Person("Alice", 88),
9 new Person("Lily", 75),
10 };
11 Arrays.sort(ps);
12 System.out.println(Arrays.toString(ps));
13 }
14 }
15 class Person implements Comparable<Person> {
16 String name;
17 int score;
18 Person(String name, int score) {
19 this.name = name;
20 this.score = score;
21 }
22 public int compareTo(Person other) {
23 return this.name.compareTo(other.name);
24 }
25 public String toString() {
26 return this.name + "," + this.score;
27 }
28 }运行上述代码,可以正确实现按
name进行排序。
未完待续
Java学习_泛型的更多相关文章
- Java学习之——泛型
1.概要 generics enable types (classes and interfaces) to be parameters when defining classes, interfac ...
- 黑马程序员:Java编程_泛型
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== 没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中.使用 ...
- 5 Java学习之 泛型
1. 基本概念 泛型是Java SE 1.5的新特性,泛型的本质是 参数化类型 ,也就是说所操作的 数据类型 被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为 ...
- Java学习笔记--泛型
一个泛型类就是具有一个或者多个类型变量的类. 我们可以只关注泛型,而不会为数据存储的细节而烦恼 . java泛型(一).泛型的基本介绍和使用 http://blog.csdn.net/lonelyro ...
- Java学习笔记——泛型
假定T不仅要指定接口的类继承.使用下面的方式: public class some<T extends Iterable<T> & Comparable<T>&g ...
- Java学习点滴——泛型
基于<Java编程思想>第四版 前言 虽然Java的泛型在语法上和C++相比是类似的,但在实现上两者是全然不同的. 语法 Java只需要一个<>就可定义泛型.在<> ...
- JAVA学习之泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及的术语:1.整个ArrayList<E>称为泛型类型 2.ArrayList< ...
- Java学习之泛型和异常
泛型 1,设计原则或目的:只要代码在编译的时候没有错误,就不会抛异常. 2,泛型通配符 :类型通配符一般是使用 ? 代替具体的类型实参.注意了,此处是类型实参,而不是类型形参!相当于(父类作用)L ...
- Java学习之==>泛型
一.什么是泛型 泛型,即“参数化类型”,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型.也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口 ...
随机推荐
- PyQt(Python+Qt)学习随笔:QScrollBar以及QAbstractSlider滚动条部件功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在Designer输入部件中Horizo ...
- windows server2012无法安装.Net FrameWork 3.5功能
问题描述: 现象1:安装完服务器系统,在安装SQL Server 2012,安装到中间提示安装SQL Server 2012过程中出现"启用windows功能NetFx3时出错"以 ...
- 西湖论剑2020MISC-Yusa_yyds
非常规USB流量分析 附件下载: 链接:https://pan.baidu.com/s/1Gjgj1EH9qmX0PYi21uYlDg 提取码:x9xn 先提取USB流量数据,使用工具: https: ...
- 第四篇 Scrum 冲刺博客
一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(25日)完成的工作 今天(26日)计划完成的工作 工作中遇到的困难 陈锐基 - 完善表白墙动态的全局状态管理 - 完成发布页面的布局 ...
- NOI 2020 D1T3 本人题解
我看了出题人本题的做法,感觉很难写,就自己胡了一个\(O((n + m) \sqrt n)\)的做法. 第一步我的想法与出题人一样,都是考虑容斥降维.对第\(i\)组询问,我们枚举两个事件中较大的一个 ...
- sqoop进行将Hive 词频统计的结果数据传输到Mysql中
使用sqoop进行将Hive 词频统计的结果数据传输到Mysql中. mysql准备接受数据的数据库与表 hive准备待传输的数据 sqoop进行数据传输 mysql查看传输结果 二:电子书 ...
- django添加检查用户名和手机号数量接口
1.1 在user/urls.py中添加 urlpatterns = [ path('count/', views.RegCountView.as_view()), # 查询用户名手机号使用量的视图, ...
- hive with as 语法
简介 with...as...需要定义一个sql片段,会将这个片段产生的结果集保存在内存中, 后续的sql均可以访问这个结果集和,作用与视图或临时表类似. 语法说明 with...as...必须和其他 ...
- 容器服务 TKE 存储插件与云硬盘 CBS 最佳实践应用
引言 随着自研上云的深入,越来越多的有状态服务对于在 TKE 集群中使用云上存储能力的需求也越来越强烈. 目前腾讯云容器服务 TKE(Tencent Kubernetes Engine已支持在 TKE ...
- 多个HDFS集群的fs.defaultFS配置一样,造成应用一直连接同一个集群的问题分析
背景 应用需要对两个集群中的同一目录下的HDFS文件个数和文件总大小进行比对,在测试环境中发现,即使两边HDFS目录下的数据不一样,应用日志显示两边始终比对一致,分下下来发现,应用连的一直是同一个集群 ...