别再让类型限制你的代码!【Java包装类+泛型】,让数据结构开发一步到位

该文章已生成可运行项目,

在这里插入图片描述

🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:Java.数据结构

在这里插入图片描述
在这里插入图片描述
【前言】

在Java中,包装类为基本数据类型提供对象封装,实现基本类型与对象的无缝转换;泛型则通过类型参数化,实现代码的通用复用并在编译期保证类型安全。二者结合,让数据结构能灵活适配多种类型,同时兼顾安全性与开发效率,是Java实现高效、通用数据操作的核心技术组合。

一、包装类

1. 什么是包装类?

包装类是Java中为8种基本数据类型提供的对应的类类型。它们位于java.lang包中,主要目的是将基本类型"包装"成对象,以便解决某些特殊场景。包装类实现了基本数据类型与对象之间的转换机制

2.基本数据类型与包装类对应表

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

3.装箱和拆箱

  • 装箱:将基本类型转换为包装类的过程
  • 拆箱:包装类转换为基本类型的过程
    int i = 10;
    Integer j = Integer.valueOf(i);//手动装箱

    int m = j.intValue();//手动拆箱
  • 自动装箱和自动拆箱
    int a = 10;
    Integer b = a;//自动装箱
    Integer c = (int)a;//自动装箱

【注意】
Integer 类型(默认范围:[-128~127])
超过范围就会新建对象
这时,a=200;b=200
如果打印a==b会返回false

public static void main(String[] args) {
    Integer a = 180;
    Integer b = 180;
    System.out.println(a == b);
}

在这里插入图片描述

二、泛型

1.什么是泛型?

泛型(Generics)是编程语言中一种强大的特性,一般的类和方法只能使用具体的类型,而泛型可以编写适用于多种数据类型的代码,而不需要为每种类型重复编写相似的代码。泛型的主要目的是提高代码的复用性、类型安全性以及代码的清晰度。

2.基本语法

class 泛型类名称<类型形参列表>{
}
class Test<T>{
}

其他写法:

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

3.引出泛型

实现一个类,该类中有一个可以存储任何类型数据的数组,并通过方法设置数组中的值,获取数组中的内容

public class Array {
    public Object[] array = new Object[10];
    public Object getPos(int pos) {
        return this.array[pos];
    }
    public void setVal(int pos,Object val) {
        this.array[pos] = val;
    }
}
 public static void main(String[] args) {
        Array myArray = new Array();
        myArray.setVal(0,10);
        myArray.setVal(1,"bba");

        String ret = (String) myArray.getPos(0);//强制类型转换

        System.out.println(ret);
    }

我们创建了一个Object类型的数组,可以存储任何类型的数据,因为Object是所有类型的父类,然后通过方法设置数组内容,但获取数据类型时会报错,发生了向下转型,这时要强制类型转换才能解决。这时,使用泛型则会更加便捷一点

使用泛型代码如下:

 public static void main(String[] args) {
        Array myArray = new Array();
        myArray.setVal(0,10);
        myArray.setVal(1,"bba");//字符串也可以存放

        String ret = (String) myArray.getPos(0);//编译报错

        System.out.println(ret);
    }
 public static void main(String[] args) {
        Array <String>myArray = new Array<String>();
        myArray.setVal(1,"bba");
        String ret = myArray.getPos(0);
        System.out.println(ret);
    }

< T >:就是占位符,表示当前类是一个泛型类;
类型后的< Integer >指定当前类型,后面就不需要强制类型转换

4.泛型的使用

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

后面的new< >里面的包装类可以不写,编译器会根据前面的包装类自动推导

【注意】:泛型只能接受类,所有的基本数据类型必须使用包装类

5.擦除机制

泛型是编译时期的机制,代码运行时没有泛型这个概念
擦除机制:

  • 在编译时,Java编译器会将泛型类型信息从代码中移除,这个过程就叫做类型擦除。

  • 擦除后,泛型类型会被替换为其边界类型(通常是Object)或者指定的类型。

  • 在必要的地方插入类型转换来保证类型安全

  • 生成桥接方式以保持多态性

上面的代码擦除后:

 class MyArray {
 public Object[] array = new Object[10];
 public Object getPos(int pos) {
 return this.array[pos];
 }
 }
 public void setVal(int pos, Object val) {
 this.array[pos] = val;
 }

5.泛型的上界

5.1语法

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

eg1:

public class Array<E extends Number>{
...
}

E 要么是Number的子类,要么是Number自己
eg2:

 public class MyArray<E extends Comparable<E>> {
 ...
 }

E必须是实现了Comparable接⼝

5.2 示例

写一个泛型类,有一个方法,求T类型数组中最大值,数组没有指定类型

  • T类型是引用类型不能通过><==比较
  • T类型擦除成Object,没有Comparable接口,所有要限定一下,给它一个上界
public class Alg <T extends Comparable<T>>{//T类型擦除成Object,没有Conmarable接口,所有要限定一下,给它一个上界
    public T findMaxVal(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(array[i].compareTo(max)>0){//T类型是引用类型不能通过><==比较
                max = array[i];
            }
        }
        return max;
    }
}
 public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] array = {5,88,9,6,56,4};
        int ret = alg.findMaxVal(array);
        System.out.println(ret);
    }

6.泛型方法

6.1语法

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

6.2 示例

泛型方法可以是static ,也可以不是static

静态方法不需要实例化引用对象,可直接调用,但参数没办法传入,so:static后面写

class Alg2{
    public static<T extends Comparable<T>> T findMaxVal(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(array[i].compareTo(max)>0){//T类型是引用类型不能通过><==比较
                max = array[i];
            }
        }
        return max;
    }
}
 public static void main(String[] args) {
        Integer[] array = {5,88,9,6,56,4};
        int ret = Alg2.findMaxVal(array);
        System.out.println(ret);
    }

7.通配符

? ⽤于在泛型的使⽤,即为通配符,用于表示未知类型

? extends 类:设置通配符上限 ,表示类型必须是T或其子类
? super 类:设置通配符下限,表示类型必须是T或其父类

【总结】

通过以上对Java包装类和泛型的详细介绍,我们可以看到它们在Java编程中的重要性和广泛应用。掌握好这两个知识点,对于编写高效、安全、可复用的Java代码具有重要意义。

在这里插入图片描述

本文章已经生成可运行项目
评论 77
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值