【数据结构】包装类&泛型

1.包装类

Java 中,由于基本类型不是继承自 Object ,为了在泛型代码中可以支持基本类型, Java 给每个基本类型都对应了 一个包装类型。

1.1.基本的数据类型对应的包装类

 1.2装箱和拆箱

       //装箱
        int a=10;
        Integer c=Integer.valueOf(a);
        System.out.println(c);
        //拆箱
        Integer b=new Integer(100);
        int d=b.intValue();
        System.out.println(d);

如图代码所示:

装箱:把一个基本数据类型转化为包装类型的过程。

拆箱:将 Integer 对象中的值取出,放到一个基本数据类型中。

1.3自动装箱与拆箱

       //自动拆箱
        Integer e=new Integer(100);
        int f=e;
        System.out.println(f);
        //自动装箱
        int t=99;
        Integer g=t;
        System.out.println(g);

 2.泛型

什么是泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。

3.引出泛型

如果我们创建一个数组,可以存储所有基本类型的数据,纳闷该如何实现呢

1. 我们以前学过的数组,只能存放指定类型的元素,例如: int[] array = new int[10]; String[] strs = new String[10];
2. 所有类的父类,默认为 Object 类。数组是否可以创建为 Object?

 代码实现如下:

        Array array=new Array();
        array.set(0,"string");
        array.set(1,1);
        Object ret=array.get(0);
        Object ret1=array.get(1);
        System.out.println(ret);
        System.out.println(ret1);


    }
}
class Array{
    Object o[]=new Object[10];
    public void set(int index,Object data){
        o[index]=data;
    }
    public Object get(int index){
        return o[index];
    }
}

输出:

string   1

可以看到完成了,存储多种类型的数据。

但是如果我们指定一种类型去接收时:必须完成强转

虽然在这种情况下,当前数组任何数据都可以存放,但是,更多情况下,我们还是希望他只能够持有一种数据类 型。而不是同时持有这么多类型。所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译 器去做检查。

 3.1.语法

定义泛型类:

class 泛型类名称 < 类型形参列表 > {
// 这里可以使用类型参数
}
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}

实例化:

泛型类 < 类型实参 > 变量名 ; // 定义一个泛型类引用
new 泛型类 < 类型实参 > ( 构造方法实参 ); // 实例化一个泛型类对象

对上述代码进行改进后:

        Array<String> array=new Array<>();
        array.set(1,"string");
        String ret= array.get(1);
        System.out.println(ret);
    }
}
class Array<T>{
    Object[] o=new Object[10];
    public void set(int index,T data){
        o[index]=data;
    }
    public T get(int index){
        return (T) o[index];
    }
}

可以看到此时在实例化的时候,就可以指定参数类型。

1.注意:再返回数据时,要进行强转,因为在数组声明时就规定了类型。 

那为啥不对T类型的数组进行实例化呢?

因为泛型不能进行实例化。

2.在set方法存入数据时,因为指定了类型为String类型,所以不能放入其他类型,否则就会报错。

3.在实例化时加入尖括号里面的内容是包装类型。

4.泛型小结 

1. 泛型是将数据类型参数化,进行传递
2. 使用 <T> 表示当前类是一个泛型类。
3. 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换

 5.泛型擦除机制

即编译的时候将所有的T擦除为Object,运行的时候没有泛型这样的概念,简单来说,泛型的擦除机制只存在于编译当中。

有关泛型擦除机制的文章截介绍:https://zhuanlan.zhihu.com/p/51452375

6.泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

6.1.语法

class 泛型类名称 < 类型形参 extends 类型边界 > {
...
}

 

public class MyArray < E extends Number > {
...
}
在这里用Number为子类的,
MyArray < Integer > l1 ; // 正常,因为 Integer Number 的子类型
MyArray < String > l2 ; // 编译错误,因为 String 不是 Number 的子类型

 这里如果没有上界,可以视为:

E extends Object

6.2.复杂实例 

如图所示:

在定义一个泛型类来比较大小时,报错了。

此时我们就要去设置一个上界。

代码如下:

  Array<String> array = new Array<>();
        String arr[] = {"hello","world"};
        String a = array.findMax(arr);
        System.out.println(a);
    }

}


class Array<T extends Comparable<T>> {
    public T findMax(T[] array){
        T max=array[0];
        for (int i = 0; i <array.length ; i++) {
            if(array[i].compareTo(max)>0){
                max=array[i];
            }
        }
        return max;
    }
}

小编在这里设置了一个上界comparable,可以进行comparaTo方法的调用,当然改为整型也是可以的。 

为啥比较是出现问题?

因为泛型的擦除机制,将T类型换成了Object,此时两个Object不能比较,要引用comparaTo方法。

7.泛型的方法

方法限定符 < 类型形参列表 > 返回值类型 方法名称 ( 形参列表 ) { ... }

实例代码:

Array1 array1=new Array1();
        String arr1[]={"hello","world"};
        String ret=array1.<String>findMax(arr);
        System.out.println(ret);

    }

}
class Array1{
    public <T extends Comparable<T>>  T findMax(T[] array){
        T max=array[0];
        for (int i = 0; i <array.length ; i++) {
            if(array[i].compareTo(max)>0){
                max=array[i];
            }
        }
        return max;


    }
}

 当然在调用时,也不用加尖括号声明类型形参,因为在编译时,会自动匹配所对应的类型。

如果不想实例化对象,可以将方法设置为静态方法。

8.总结

由于小编能力有限,可能存在一些有误的地方,希望各位uu提出宝贵意见。

制作不易,麻烦给小编点个赞吧。

 

 

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值