内容
1.泛型简单介绍
2.类使用泛型
3.接口使用泛型
4.通配符
5.设置泛型上限和下限
6.泛型应用之使集合自动排序
一.泛型简单介绍
泛型这一块在c++博客中写过,这里就不再引用。因为泛型在后期安卓开发用的不多,所以只需掌握简单应用即可。
1.用在哪
一般用于Collection和Map
2.何时用
在定义接口、类、方法和变量的时候,需要操作数据,但是不清楚使用者需要哪种数据。这种情况下就需要使用泛型
3.注意点
①在定义的时候可以使用泛型来代表任意的类型,但是在使用的时候(定义变量、创建对象)必须要传递实际类型。
②泛型可以用E表示,也可以用T表示。
二.类使用泛型
1.简单使用示例
class Test<E>{}
主方法里面
Test<String> test;new Test<String>();
当创建对象的时候用了变量去保存对象了,这时候变量类型需要声明具体类型,但是new后面可以省略类型
Test<String> test2 = new Test();2.泛型变量的应用示例
class Test<E>{E var1;
}
public class 测试程序 {
public static void main(String[] args) {
Test<String> test2 = new Test();
test2.var1 = "jack";
System.out.println(test2.var1.getClass());
}
}
结果
class java.lang.String
三.接口使用泛型
1.两种使用方式
①明确用一个类实现接口,进而使用这个接口
②使用匿名内部类使用这个接口
2.使用示例
//泛型接口interface Test<T>{
void test(T t);
}
//类继承一个接口时,
//1.指定接口的类型
class test1 implements Test<String>{
@Override
public void test(String t) {
// TODO 自动生成的方法存根
}
}
//2.指定当前类为泛型
class test2<T> implements Test<T>{
@Override
public void test(T t) {
// TODO 自动生成的方法存根
}
}
public class 测试程序 {
public static void main(String[] args) {
//一.明确用一个类实现接口,进而使用这个接口
Test<String> test = new test2<String>();//test2后面的String可以省略
//二.使用匿名内部类使用这个接口
Test<String> test3 = new Test<String>() {
@Override
public void test(String t) {
// TODO 自动生成的方法存根
}
};
}
}
四.通配符
1.何时用
当在使用泛型时,如果不确定到底是什么类型,那么可以使用 ? 来表示任意类型,这个?就是泛型。但是真真正正使用的时候,还是要指定确定类型,不能直接一个?
2.泛型方法
当方法所在的类不是泛型类的时候,必须在方法前面(访问权限修饰符后)使用<T>或者<E>来表示需要使用泛型
如果类是泛型类,就不需要在方法前面指定了
2.使用示例(包括泛型方法的使用)
import java.util.*;//泛型方法
//当类不是泛型类的时候,必须在方法前面使用<T>或者<E>来表示需要使用泛型
//如果类是泛型类,就不需要在方法前面指定了
class Foo{
public<T> void test(T t) {
System.out.println(t);
}
//这里也用到了泛型,List是泛型接口,这里可以直接用List,相当于没有指定类型
//这里也不能List<Object> ,因为Java的集合类型是不能自动转型的
//也就是List<Child> 的东西自动转到 List<Father>是不可以的
//即List<String>不能转List<Object>
//但是按照规定,又需要指定类型,所以就可以使用一个?
public void showList(List<?> list) {
for(int i = 0;i < list.size();i++) {
list.get(i);
System.out.println(list.get(i));
}
}
}
public class 测试程序 {
public static void main(String[] args) {
Foo foo = new Foo();
foo.test("jack");
ArrayList<String> names = new ArrayList<>();
names.add("merry");
names.add("john");
foo.test(names);
foo.showList(names);
}
}
结果
jack
[merry, john]
merry
john
3.注意点
Java的集合类型是不能自动转型的
五.设置泛型上限和下限
1.介绍
设置上限和下限其实涉及继承。就是虽然按照语法你可以随意给我传类型,但是在实际情况中是有限制的。
比如小明要喝牛奶,你可以给他任意牛奶,比如蒙牛牛奶等等,但是最少你得是个牛奶,也就是你必须继承(有可能直接继承也有可能间接继承)牛奶,即上限是个牛奶。下限就是正常的牛奶牌子,比如各种正常品牌的牛奶,这都是可以的。但是下限、底线是这是能喝的,正常的健康的牛奶,不能瞎造一个就拿来喝,这是下限。
2.上限设置使用示例
import java.util.*;class Cat{
}
//设置泛型的上限 extends
interface IFood{
}
class Milk implements IFood{
}
class TianyouMilk extends Milk{
}
//上限是IFood,可以传过来IFood,也可以是Milk,也可以是TianyouMilk
class Student<T extends IFood>{//表示指定传递过来的类型的父类必须是IFood,或者其子类。
public void eat(T t) {
}
}
public class 测试程序 {
public static void main(String[] args) {
Student<Milk> xw ;
Student<TianyouMilk> zs;
//Student<Object> zt;//这样就不行了
//Student<Cat> ca;//这样依然不行
}
}
3.下限设置使用示例
//使用super来设置下限class STest{
public<T> void copy(List<T> src,List<? super T> dest) {
//最少也得是T类型才能copy给我
}
}
六.泛型应用之使集合自动排序
1.功能介绍
之前的集合排序都是:先把数据传进去,然后调用排序方法。那么可不可以改进一下,使数据传进去就自动排序了呢?
答案是肯定的,具体过程请看使用示例。
2.具体代码
类① Person类
注意点:
(1)实现Comparable接口
(2)重写compareTo方法,注意返回的值是如何表示的。
String name;
public Person(String name) {
this.name = name;
}
public String toString() {
return name;
}
@Override
public int compareTo(Person arg0) {
// TODO 自动生成的方法存根
return name.compareTo(arg0.name);
}
}
类②SortList类
注意点:
(1)这个类是自己创建的,继承ArrayList,所以有ArrayList的方法。
(2)因为要实现特定功能,所以要重写add方法。
(3)注意第一个extends,这个表示这个泛型的上限必须是Comparable,对应的Person类实现了Comparable接口
(4)? 后面的super表示?的下限是 T类型,因为是T要进行比较,不能乱给我别的类型
//这个类的功能:
//在系统原有的基础之上添加一个功能:一将数据加入数组,就排好序
public class SortedList<T extends Comparable<? super T>> extends ArrayList<T>{
//添加数据就排好序
//1.先调用系统的方法
//2.把系统的add方法进行重写
/** public boolean add(T t) {
return super.add(t);
}**/
public boolean add(T t) {
//将数据排序
boolean result = super.add(t);
//对数组排序
Collections.sort(this);
//返回结果
return result;
}
}
类③主方法所在类
注意点:这里直接使用自己写的类创建集合即可。
import java.util.*;public class 测试程序 {
public static void main(String[] args) {
SortedList<Person> lists = new SortedList<Person>();
lists.add(new Person("jack"));
lists.add(new Person("black"));
lists.add(new Person("merry"));
System.out.println(lists);
}
}
结果
[black, jack, merry]
总结
前几天以为没有课程,就没听课,到昨天才发现课程一直在更新,所以就有点尴尬。但是还是不要慌,落下的部分慢慢去学,这一遍一定要学透彻。现在有两个demo,一个是扑克牌的,一个是联系人的,虽然写完了,但是还没有着手研究。我一定会抽时间写出来的。