数据结构的学习历程09

泛型

泛型的实现

泛型的优点
1、可以在编译的时候的时候,自动进行类型的检查
2、存放元素的时候,不需要强制类型转换。
3、编译的时候起作用,运行的时候被擦除
泛型的缺点
1、不能new泛型类型的数组
若要newT类型的数组则应: T[] t = (T[])new Object[];
2、基本类型不能作为泛型类型 的参数:如:int
泛型如何工作:
擦除机制:是在编译期间存在的一种机制,泛型的概念只存在在编译期间(在编译期间,将T擦除为Object,擦除不是替换)

class Group<T>{
    public T[] elem;
    public int size;

    public Group(){
        this.elem = (T[]) new Object[10];
        this.size = 0;
    }
    public void add(T val){
        this.elem[this.size]=val;
        size++;
    }
    public T get (int n){
        if ( n<0 ||n>=this.size) return null;
        return this.elem[n-1];
    }
}
public class Demo06 {
    public static void main(String[] args) {
        Group<Integer> lit= new Group<>();
        lit.add(1);
        lit.add(2);
        System.out.println(lit.get(1));


		Group lit= new Group<>();//此处也可以不使用泛型,此时默认为Object类型
    }
}
泛型的参数(了解)

T 表示 Type
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
S, U, V 等等 - 第二、第三、第四个类型

泛型接口

泛型接口的实现

interface IA<T>{//接口不能实例化,接口命名加I 表示此类是接口
    void act();
    default void sleep(){//jdk1.8开始,接口中的方法也可以有具体的实现,但必须加default修饰
        System.out.println("睡!!");
    }
}
class B<T> implements IA<T> {
    public void act() {//重写接口方法
        System.out.println("站!!");
    }
}

扩展:

interface IA<T,K>{//接口不能实例化,接口命名加I 表示此类是接口
    void act();
    default void sleep(){//jdk1.8开始,接口中的方法也可以有具体的实现,但必须加default修饰
        System.out.println("睡!!");
    }
}
class B<T,K,V> implements IA<T,V> {//实现的接口必须与原接口中泛型参数的数量一致,泛型的类型必须在实现此接口的泛型参数中出现。
    public void act() {//重写接口方法
        System.out.println("站!!");
    }
}
class C<T> extends Stu{//也可继承一个不带泛型的类
}
泛型继承(类型边界)

如下,则T这个参数类型,只能为Number的子类类型,而在编译时,也将把T擦除为Number类型,而不是Object。

class Group<T extends Number> {
}

此时Number就叫做泛型的上界,而泛型是没有下界的。

泛型方法
class StaticMethod{
    public static<T> T mathod(T val){
        return val;
    }
    <T> T mathod1(T val){
    return val;
}
public class Demo {
    public static void main(String[] args) {
        int a = StaticMethod.mathod(1);//此处使用类型推导
        String str = StaticMethod.mathod("qqqq");//此处使用类型推导

		int a = new StaticMethod().mathod1(1);//此处使用类型推导
		String str = new StaticMethod().mathod1("qqqq");//此处使用类型推导
		int a = new StaticMethod().<Integer>mathod1(1);//此处不使用类型推
		int a = new StaticMethod().<String>mathod1("lit");//此处不使用类型推
		
    }
}

通配符

上界与下界,例如

class CustomerList<T>{
	public func(List<? extends Number> list) {
	}
}

此时,func方法接收的返回值类型为List且里面存储的元素必须是Number子类类型的元素的类型,如:传入一个List<String>类型的,则会编译错误。

class CustomerList<T>{
	public func(List<? super Integer> list) {
	}
}

而此时,func方法接收的返回值类型为List且里面存储的元素必须是Number父类类型的元素的类型,如:传入一个List<Doublie>类型的,则会编译错误,此时应该传入Integer或Number或Object等
注意:泛型无下界!!!

泛型的父子类型

List<Number>不是List<Doublie>的父类型
List<Object>也不是List<Number>的父类型
List<?>是List<? extends Number>的父类型
List<? extends Number>List<Integer>的父类型

比较

如果某个类需要比较这个类的实例化对象,那么这个泛型类就需要重写equals方法,或者实现Comparable接口重写comparaTo方法,或实现Comparator接口重写compare方法
习题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值