【数据结构】包装类泛型

news2024/9/9 0:25:51

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提出宝贵意见。

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

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1958377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙应用框架开发【简单时钟】 UI框架

简单时钟 介绍 本示例通过使用ohos.display接口以及Canvas组件来实现一个简单的时钟应用。 效果预览 使用说明 1.界面通过setInterval实现周期性实时刷新时间&#xff0c;使用Canvas绘制时钟&#xff0c;指针旋转角度通过计算得出。 例如&#xff1a;"2 * Math.PI / …

Synchronized的锁升级过程是怎样的?

文章目录 一、Synchronized的使用1、修饰实例方法2、修饰静态方法3、修饰代码块4、总结&#xff1a; 二、Monitor1、Java对象头1.1 32 位虚拟机的对象头1.2 64位虚拟机的对象头 2、Mark Word 结构3、Moniter4、Synchronized 字节码5、轻量级锁6、锁膨胀7、自旋优化8、偏向锁9、…

Python for循环迭代原理(迭代器 Iterator)

在使用Python时&#xff0c;我们经常会使用for循环来访问容器对象&#xff08;列表、字符、字典等&#xff09;中的元素。其幕后实际是通过迭代协议来完成的&#xff0c;迭代是一种依次访问对象中元素的方式&#xff0c;for循环在对象上调用iter()函数生成一个迭代器&#xff0…

从后端开发视角认识向量数据库

以ChatGPT为代表的大语言模型应用自问世以来已经火了好几年。在这期间国内外类似产品层出不穷&#xff0c;甚至公司内部团队都开发了好几个AI小助手。刚好最近看了几篇关于大语言模型应用开发的文章&#xff0c;借此了解了一下应用层面的基本知识&#xff0c;也算是接触到了大语…

轻松入门Linux—CentOS,直接拿捏 —/— <2>

一 、权限问题详细讲解 读写的权限可以分别写成 r, w, x 总共有九个权限&#xff0c;可以分组三大组分别是&#xff1a; user&#xff1a;当前文件所属用户的权限 group&#xff1a;与当前文件所属用户同一组的用户权限 others&#xff1a;其他用户的权限 故使用 u, g, o 来代表…

Qt Creator 与 ESP-IDF QEMU 模拟器使用指南

标题: Qt Creator 与 ESP-IDF QEMU 模拟器使用指南 概要: 本文为开发者提供了使用 Qt Creator 和 ESP-IDF QEMU 模拟器进行 ESP32 开发的详细指南&#xff0c;包括环境准备、项目创建和编译、模拟器设置、编程和调试等方面的内容。通过本指南&#xff0c;可以快速上手 Qt Crea…

bean管理

获取bean bean作用域 第三方bean

如何使用虚拟机如何安装 Kali Linux ?

1.下载虚拟机&#xff1a;https://www.virtualbox.org/wiki/Downloads 选择你的系统版本 2.下载kali linux系统镜像&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 全部下载完成后&#xff0c;我们会得到以下文件&#xff01; 1.压缩Kali Linux压缩包 2.安…

OpenCV C++的网络实时视频流传输——基于Yolov5 face与TCP实现实时推流的深度学习图像处理客户端与服务器端

前言 在Windows下使用TCP协议&#xff0c;基于OpenCV C与Yolov5实现了一个完整的实时推流的深度学习图像处理客户端与服务器端&#xff0c;为了达到实时传输的效果&#xff0c;客户端使用了多线程的方式实现。深度学习模型是基于onnxruntime的GPU推理。&#xff0c;实现效果如…

跨境电商网红营销SOP流程2.0丨出海笔记

之前几位大神已经在出海笔记分享过网红营销一些很落地的干货&#xff0c;无论是想自己找红人还是找Agency都很有必要了解下这里面的流程的&#xff0c;下面我大概总结了一个SOP2.0 供大家快速上手&#xff1a; 以上是网红营销的SOP&#xff0c;做到以上部分基本60分没问题了…

【云原生】Kubernetes中crictl的详细用法教程与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

AI作图接口要怎么调用呢?

一、什么是AI作图&#xff1f; 基于AI大模型的深度学习算法和大规模的图像数据训练&#xff0c;输入图片和关键词&#xff0c;可生成独特及富有创意的山水风格图片。 二、AI作图使用场景有哪些呢&#xff1f; 1.广告与营销&#xff1a; 为产品制作吸引人的宣传海报、广告图片…

OpenStack——nova

计算服务nova nova简介——计算服务nova&#xff08;Iaas侧服务&#xff09; * 提供大规模、可扩展、按需自助服务的计算资源 * 支持管理裸机&#xff0c;虚拟机和容器 * Nova即OpenStack Compute service&#xff0c;负责提供计算资源的模块&#xff0c;也是OpenStack中的核…

以西门子winCC为代表的组态界面,还是有很大提升空间的。

组态界面向来都是功能为主&#xff0c;美观和体验性为辅的&#xff0c;这也导致了国内的一些跟随者如法炮制&#xff0c;而且很多操作的工程师也是认可这重模式&#xff0c;不过现在一些新的组态软件可是支持精美的定制化界面&#xff0c;还有3D交互效果&#xff0c;这就是确实…

坐标系转换公式

坐标系转换2种情况&#xff1a; 一、XOY坐标系不动&#xff0c;点P(x, y) 沿顺时针方向旋转 θ \thetaθ&#xff0c;得在XOY坐标系的坐标为P(x′, y′) 设某点与原点连线和X轴夹角为b度&#xff0c;以原点为圆心&#xff0c;逆时针转过a度 , 原点与该点连线长度为R, [x,y]为…

前端开发:Vue2.0桌面组件库-Element

引入Element的步骤&#xff1a; 1.在vscode终端中执行命令&#xff08;需要联网&#xff09; 下载成功 2.在main.js中导入element.ui组件库。 同上&#xff0c;自定义的组件需要先在根组件中引入。 3.访问官网&#xff0c;复制调整代码

C语言:指针的进阶

指针的进阶 一、字符指针&#xff08;一&#xff09;字符指针&#xff08;二&#xff09;常量字符串和字符数组 二、指针数组和数组指针&#xff08;一&#xff09;指针数组 int *p1[10]&#xff08;二&#xff09;数组指针 int (*p2)[10] 三、函数指针&#xff08;一&#xff…

【Unity编辑器拓展】GraphView自定义可视化节点

1、创建节点区域脚本 其中的new class UxmlFactory&#xff0c;可以让该元素显示在UI Builder中&#xff0c;我们就可以在Library-Project中看到我们新建的这两个UI元素&#xff0c;就可以拖入我们的UI窗口编辑了 public class NodeTreeViewer : GraphView {public new class…

UnityShaderUI编辑器扩展

前言&#xff1a; 当我们在制作通用Shader的时候&#xff0c;避免不了许多参数混杂在一起&#xff0c;尽管在材质面板已经使用过Header标签来区分&#xff0c;但是较长的Shader参数就会导致冗余&#xff0c;功能块不够简约明了&#xff0c;如图&#xff1a; 对于Shader制作者来…

如何在 VPS 上安装和使用 VirtualMin

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 关于 Virtualmin Virtualmin 是 Webmin 的一个模块&#xff0c;允许对&#xff08;多个&#xff09;虚拟专用服务器进行广泛的管理。您…