Java语法进阶10-泛型
泛型
泛型:参数化的类型,即把数据类型当做参数来传递
有的地方又称为泛化的类型,用一个单个大写字母,例如<T>来代表任意类型,这个T就是泛化的类型。
泛型的好处:
(1)表示某个变量的类型更灵活
(2)安全:有了泛型,在编译期间就可以避免不符合类型的数据赋值
(3)避免数据类型转换
泛型类或泛型接口
【修饰符】 class 类名<类型变量列表/泛型类型形参列表>{
}
【修饰符】 interface 接口名<类型变量列表/泛型类型形参列表>{
}
使用
(1)创建对象时
在创建类的对象时指定类型变量对应的实际类型参数,指定泛型实参时,必须左右两边一致,不存在多态现象
(2)继承、实现接口
在继承泛型类或实现泛型接口时,指定类型变量对应的实际类型参数
注意
(1)<类型变量列表/泛型类型形参列表>:使用单个的大写字母表示,例如:<T>,<E>,<R>...
(2)<类型变量列表/泛型类型形参列表>:可以多个,每个之间使用,分割,例如:<K,V>
(3)如果要指定<类型变量列表/泛型类型形参列表>的实际类型,必须是引用数据类型,不能是基本数据类型
(4)类和接口上的类型形参不能用于静态方法中
(5)<类型变量列表/泛型类型形参列表>可能有上限,< T extends 上限1 >
类型变量的上限
当在声明类型变量时,如果不希望这个类型变量代表任意引用数据类型,而是某个系列的引用数据类型,那么可以设定类型变量的上限。
< T extends 上限1 & 上限2 ...>
上限中类只能有一个,如果有必须在最左边,接口的话可以多个。多个上限之间是&(与)的关系。
如果在声明<类型变量>时没有指定任何上限,默认上限是java.lang.Object。
泛型擦除
当使用参数化类型的类或接口时,如果没有指定泛型,会发生泛型擦除,泛型的类型就会自动按照最左边的第一个上限处理。如果没有指定上限,上限即为Object。
泛型方法
如果我们定义类、接口时没有使用<类型变量>,但是某个方法定义时或静态方法定义时,想要自己定义<类型变量>就可定义泛型方法
语法:
【修饰符】 <类型变量列表/泛型类型形参列表> 返回值类型 方法名(【数据形参列表】)【throws 异常列表】
使用:
方法被调用时,根据方法的实参的类型自动推断。
注意:
泛型方法的定语与泛型类的定义注意点相同,并且泛型方法可定义静态方法
每一个泛型方法的<类型变量列表/泛型类型形参列表>是独立的,和别的方法无关,和类上面的泛型也无关
类型通配符
当我们声明一个方法时,某个形参的类型是一个参数化的泛型类或泛型接口类型(Map<K,V>),但是在声明方法时,又不确定该泛型实际类型,我们可以考虑使用类型通配符。
形式:
(1)泛型类/接口名<?> ?代表任意引用数据类型
(2)泛型类/接口名<? extends 上限> ?代表的是该上限或上限的子类类型
(3)泛型类/接口名<? super 下限> ?代表的是该下限或下限的父类类型
注意:
<?>:不可变,因为<?>类型不确定,编译时,任意类型都是错
<? extends 上限>:不可变,因为<? extends 上限>的?可能是上限或上限的子类,即类型不确定,编译按任意类型处理都是错。
<? super 下限>:可以将值修改为下限或下限子类的对象,因为<? super 下限>?代表是下限或下限的父类,那么设置为下限或下限子类的对象是安全的。
泛型的其他小问题
1、<>在左右两边 类型必须一致
2、JDK1.7之后允许右边<>里面空着,根据左边的自动推断
3、try...catch的catch里面不能使用T这种来代表任意异常类型。
4、泛型类不能创建数组对象
5、泛型可用于可变形参列表(T... t)
超类通配符<? super 下限>主要用于灵活的写入和比较,而<? extends 上限>主要用于读写,不能写入或者修改
数组算法升华
1、数组的反转
方法一:
1、借助一个新数组
2、首尾对应位置交换
缺点:需要借助一个数组,浪费额外空间,原数组需要垃圾回收
方法二:
数组对称位置的元素互换。
或
2、数组的扩容
(1)先创建一个新数组,可以扩容为原来的1.5倍、2倍等
(2)把旧数组的数据赋值到新数组中
(3)把新元素添加到newArr的最后
(4)如果下面继续使用arr,可以让arr指向新数组
数组扩容太多会造成浪费,太少会导致频繁扩容,效率低下
3、数组元素的插入
(1)判断数组是否需要扩容
如果需要,先扩容
(2)把[index]位置和它后面的元素往右移动
(3)在[index]位置放入新元素
4、数组元素的删除
(1)把[index+1]位置和它后面的元素往左移动
(2)把当前数组的最后一个元素还原(0/null)
5、数组的二分查找
二分查找:对折对折再对折
要求:要求数组元素必须支持比较大小,并且数组中的元素已经按大小排好序
6、数组的直接选择排序
int[] arr = {....};
//轮数 = arr.length-1
for(int i=0; i<arr.length-1; i++){
//(1)找出本轮最小值
int minIndex = i;
for(int j=i+1; j<arr.length-1; j++){
if(arr[minIndex] > arr[j]){
minIndex = j;
}
}
//(2)如果本轮最小值不在它应该在的位置
if(minIndex != i){
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
最新文章
- 【干货分享】流程DEMO-人员调动流程
- bzoj1854--并查集
- [sourceTree]这是一个无效的源路径
- SortedSet接口
- 解决postgresql -- ERROR: 42601: query has no destination for result data
- node.js在linux下的安装
- 【GK101 谐波数据生成器】上位机软件升级(版本:1.1)
- LayoutInflater和inflate()方法的用法
- 漫游Kafka设计篇之数据持久化
- iPhone6设计自适应布局
- 安装Windows2008操作系统 - 初学者系列 - 学习者系列文章
- [ACdream]女神教你字符串——导字符串
- CNN试验记录
- centos7下安装docker(17.2docker监控---weave scope)
- 【BZOJ4764】弹飞大爷
- Spring + Mybatis 读写分离
- mysql 架构~多写模式MGR
- python3爬虫二
- ScrollView滚动条的各种设置
- JMeter:全面的乱码解决方案