前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【AI驱动的泛型数据结构:智能计算的核心】

【AI驱动的泛型数据结构:智能计算的核心】

作者头像
ImAileen
发布2024-12-21 20:13:44
发布2024-12-21 20:13:44
9700
代码可运行
举报
运行总次数:0
代码可运行

泛型

泛型:就是可以将类型作为参数进行传递。

代码语言:javascript
代码运行次数:0
复制
/**
 *
 * @param
 * <T>:表示当前类是一个泛型类
 */

class Person{

}

class MyArray<T>{
//    public Object[] array = new Object[10];
    //因为不能直接实例化一个泛型数组
    //将Object类型的数组转换成T[]类型
    public T[] array = (T[])new Object[10];

    public void setValue(int pos , T val){
        array[pos] = val;
    }

    public T getValue(int pos){
        return array[pos];
    }
}
代码语言:javascript
代码运行次数:0
复制
public class Test {
    //目标:存放指定元素
    public static void main(String[] args) {
        MyArray<String> myArray = new MyArray<>();
        myArray.setValue(0,"Kevin");
        myArray.setValue(1,"Alex");
        myArray.setValue(2,"Aileen");

        String str = myArray.getValue(2);
        System.out.println(str);

//      =================================================

        MyArray<Integer> myArray2 = new MyArray<>();
        myArray2.setValue(0,1);
        myArray2.setValue(1,99);
        int val = myArray2.getValue(1);
        System.out.println(val);

//      =================================================

        MyArray<Person> myArray3 = new MyArray<>();

//        //因为我的getvalue返回的是Object类型,所以要通过(Srtring)进行强制转换
//        String str = (String) myArray.getValue(2);
    }
  • 泛型的意义:
    • 1.在编译的时候检查数据类型是否正确。
    • 2.在编译时期辅助进行类型转换。
  • ⚠️注意在<>内不能是基本数据类型,只能是引用类型。

泛型语法

代码语言:javascript
代码运行次数:0
复制
class 泛型类名称<类型参数列表>{
    //类型参数
    }
代码语言:javascript
代码运行次数:0
复制
class ClasssName<T,T2,T3,...,Tn>{
    }
  • 类名后的<T>代表占位符,表示当前类是一个泛型类。类型形参一般使用一个大写字母表示,常用的名称有:

符号

含义

E

Element

K

Key

V

Value

N

Number

T

Type

S, U, V等

第二、第三、第四个类型

  • 泛型是在编译时的一种机制(擦除机制),这意味着在运行的时候没有泛型的概念,并且在JVM中没有泛型的概念。所以不能new泛型类型的数组。
  • 在实例化对象的时候在类型后加入<Integer>指定类型,这就可以使得我们后面调用对应的方法的时候无需进行强转,因为他已经自动帮我们强制转换好了。

泛型的使用

基本使用
代码语言:javascript
代码运行次数:0
复制
MyArray<Integer> list = new MyArray<Integer>();
  • ⚠️注意:泛型只能接受类,所有基本类型数据都必须使用包装类,比如说:int类型要使用其包装类:Integer。
简版使用
代码语言:javascript
代码运行次数:0
复制
MyArray<Integer> list = new MyArray<>();
  • 后面<>里面的类型可省略,因为编译器会根据前面的<>中的类型自动推导出后面的类型。
  • <>只能放引用数据类型,不能放基本数据类型。
裸类型
代码语言:javascript
代码运行次数:0
复制
MyArray list = new MyArray();
  • 将后面的<>省略掉。最好不要使用,因为这是为了兼容老版本的API保留的机制。

🏷️小结:泛型的优点:将数据类型参数化,编译时自动进行类型检查和转换。


代码语言:javascript
代码运行次数:0
复制
class MyArray<T> {
    public T[] array = (T[])new Object[10];

    public T getPos(int pos) {
        return this.array[pos];
    }

    public void setVal(int pos, T val) {
        this.array[pos] = val;
    }

    public T[] getArray() {
        return array;
    }
}

public class Main {
    public static void main(String[] args) {
        MyArray<Integer> myArray1 = new MyArray<>();
        Object[] strings1 = myArray1.getArray();
        System.out.println(strings1);
        Integer[] strings2 = myArray1.getArray(); // 这里会出现类型转换警告
        System.out.println(strings2);
    }
}
  • 报错原因: Object类型的数组不能具体强转成一个具体类型的数组,因为Object类型的数组有可能存储的不是这种类型的元素。返回的Object数组里面,可能存放的是任何的数据类型,可能是String,可能是Person,运行的时候,直接转给Integer类型的数组,编译器认为是不安全的。
  • 此外,由于数组是一种单独的数据类型,数组之间没有继承关系这样的说法,所以不能将Object数据类型的数组强转成其它类型的数组,或者将其直接进行赋值。
  • 直接将Integer修改为Object报错即可消失。

Java中泛型的正确书写格式

  • ⛔️问题引入
  • ✅️解决方案
代码语言:javascript
代码运行次数:0
复制
    public Object[] array = new Object[10];
    public void setValue(int pos , T val){
        array[pos] = val;
    }

    public T getValue(int pos){
        return (T)array[pos];//返回值通过(T)强转成Object类型
    }

public class Test {
    //目标:存放指定元素
    public static void main(String[] args) {
        MyArray<String> myArray4 = new MyArray<>();
        MyArray<Integer> myArray5 = new MyArray<>();
        }
}

泛型的上界

代码语言:javascript
代码运行次数:0
复制
// 定义一个泛型类,其类型参数E限定为Number的子类型
public class MyArray<E extends Number> {
    // 类的其余部分
}

// 正确的使用,因为Integer是Number的子类型
MyArray<Integer> l1; 

// 错误的使用,因为String不是Number的子类型,会导致编译错误
MyArray<String> l2; 

// 编译错误信息示例
/*
error: type argument String is not within bounds of type-variable E
MyArrayList<String> l2;
       ^
where E is a type-variable:
    E extends Number declared in class MyArrayList
*/

写一个泛型类,求一个数组当中的最大值

  • 因为比较的时候这个数组元素会被擦成引用类型即Object,由于引用数据类型不能直接通过大于,等于号进行比较大小,需要通过compareTo这个接口来比较大小,但是由于Object也没有实现compareTo这个接口,所以第39行会报错。
  • 如果需要比较则需要给它一个边界,如下代码中的①和②
代码语言:javascript
代码运行次数:0
复制
/*写一个泛型类,求一个数组中的最大值*/
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
    public T findMaxVal(T[] array){
//        假设第一个就是最大的
        T max = array[0];
        for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
            if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
                max = array[i];
            }
        }
        return max;//将最大值赋值给max并返回
    }
}


public class Test {
    public static void main(String[] args) {
        Integer[] array = {1,4,3,8,7,5};
        Alg<Integer> alg = new Alg<>();
        //因为Integer实现了Comparable接口所以可以直接创建对象
//        现在这个Integer就是上面的T
        System.out.println(alg.findMaxVal(array));
    }
  • 此外,当TInteger时,由于它已经实现了comparable这个接口,所以可以直接使用这个接口,不需要重写compareTo这个方法

泛型上界的写法

代码语言:javascript
代码运行次数:0
复制
T extends Comparable<T>
如果age这个属性是public的->可以直接通过对象.获取对应的数值
代码语言:javascript
代码运行次数:0
复制
/*写一个泛型类,求一个数组中的最大值*/
class Person implements Comparable<Person>{
    public int age ;

    // 构造函数,用于初始化Person对象的age属性,这才能使得你在后面调用这个方法去进行不同年龄的比较
    public Person(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }
}

//---------------------------------------------------------------------------------
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
    public T findMaxVal(T[] array){
//        假设第一个就是最大的
        T max = array[0];
        for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
            if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
                max = array[i];
            }
        }
        return max;//将最大值赋值给max并返回
    }
}

//---------------------------------------------------------------------------------
public class Test {
    public static void main(String[] args) {
        Person[] array2 = {new Person(77),new Person(99),new Person(66)};
        Alg<Person> alg2 = new Alg<>();
        //当T为Person作为参数传入时
        // 由于它并没有实现comparable这个接口所以他会报错
        //解决办法:
//        创建Person这个类,然后去实现comparable这个接口
//        最后重写compareTo这个方法。
        System.out.println(alg2.findMaxVal(array2).age);
    }

如果age这个属性是private的->通过get方法获取即可在main方法中打印
代码语言:javascript
代码运行次数:0
复制
/*写一个泛型类,求一个数组中的最大值*/
class Person implements Comparable<Person>{
    private int age ;

    // 构造函数,用于初始化Person对象的age属性,这才能使得你在后面调用这个方法去进行不同年龄的比较
    public Person(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }
}

//---------------------------------------------------------------------------------
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
    public T findMaxVal(T[] array){
//        假设第一个就是最大的
        T max = array[0];
        for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
            if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
                max = array[i];
            }
        }
        return max;//将最大值赋值给max并返回
    }
}


public class Test {
    public static void main(String[] args) {
        Person[] array2 = {new Person(77),new Person(70),new Person(66)};
        Alg<Person> alg2 = new Alg<>();
        //当T为Person作为参数传入时
        // 由于它并没有实现comparable这个接口所以他会报错
        //解决办法:
//        创建Person这个类,然后去实现comparable这个接口
//        最后重写compareTo这个方法。
        System.out.println(alg2.findMaxVal(array2).getAge());
    }

泛型方法

代码语言:javascript
代码运行次数:0
复制
方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
代码语言:javascript
代码运行次数:0
复制
    public<T extends Comparable<T>> T findMaxVal(T[] array){ }
普通泛型方法
代码语言:javascript
代码运行次数:0
复制
/*泛型方法*/
class Alg2{
    public<T extends Comparable<T>> T findMaxVal(T[] array){
//        假设第一个就是最大的
            T max = array[0];
            for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
                if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
                    max = array[i];
                }
            }
            return max;//将最大值赋值给max并返回
    }
}


public class Test {
    public static void main(String[] args) {
        Alg2 alg2 = new Alg2();
        Integer[] array = {1,4,3,8,7,5};
//        调用方法的两种写法
//        写法①
        System.out.println(alg2.<Integer>findMaxVal(array));
//        写法②:省略<Integer>
        System.out.println(alg2.findMaxVal(array));//根据实参array的值知道T是什么
    }
静态泛型方法
  • 如果这个方法是静态方法就可以无需创建对象,直接通过类名访问方法
代码语言:javascript
代码运行次数:0
复制
/*泛型方法*/
class Alg3{
    public static <T extends Comparable<T>> T findMaxVal(T[] array){
//        假设第一个就是最大的
        T max = array[0];
        for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
            if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
                max = array[i];
            }
        }
        return max;//将最大值赋值给max并返回
    }
}


public class Test {
    public static void main(String[] args) {
        Integer[] array = {1,4,3,10,7,5};
//        调用方法的两种写法
//        写法①
        System.out.println(Alg3.<Integer>findMaxVal(array));
//        写法②:省略<Integer>
        System.out.println(Alg3.findMaxVal(array));//根据实参array的值知道T是什么
    }
  • 相比于Alg2,静态方法Alg3少了类对象的创建。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 泛型
  • 泛型语法
  • 泛型的使用
    • 基本使用
    • 简版使用
    • 裸类型
  • Java中泛型的正确书写格式
  • 泛型的上界
  • 写一个泛型类,求一个数组当中的最大值
  • 泛型上界的写法
    • 如果age这个属性是public的->可以直接通过对象.获取对应的数值
    • 如果age这个属性是private的->通过get方法获取即可在main方法中打印
  • 泛型方法
    • 普通泛型方法
    • 静态泛型方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档