【数据结构Java版】 初识泛型和包装类

news2024/11/28 20:40:00

目录

1.包装类

1.1基本数据类型以及它们所对应的包装类

1.2装箱和拆箱

1.3自动装箱和自动拆箱

2.什么是泛型

3.引出泛型

4.泛型类的使用

4.1语法

  4.2示例

4.3类型推导

5.泛型是如何编译的

5.1擦除机制

5.2正确的写法

6.泛型的上届

6.1语法

 6.2示例               


1.包装类

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

1.1基本数据类型以及它们所对应的包装类

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

注:除了int类型和char类型的包装类是Integer和Character,其它所有的基本数据类型对应的包装类都是它的首字母大写。

1.2装箱和拆箱

 public static void main(String[] args) {
        int a=199;
        //装箱操作,新建一个Integer对象,将a的值存入对象的某个属性中
        Integer integer1=Integer.valueOf(a);
        Integer  integer2=new Integer(a);
        //拆箱操作 将Ingeter中的值取出,存放进一个基本数据类型中
        int b=integer1.intValue();
        //比较两个包装类大小的时候,建议使用equals方法,而不是==
        System.out.println(integer2.equals(integer1));
        //无论是打印包装类类型的值 还是基本类型的值 结果都是一样的
        System.out.println(integer1);
        System.out.println(b);
    }

1.3自动装箱和自动拆箱

  在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,Java提供了自动机制。

        int i = 10;
        Integer ii = i; // 自动装箱
        Integer ij = (Integer)i; // 自动装箱
        int j = ii; // 自动拆箱
        int k = (int)ii; // 自动拆箱
   
    

 

2.什么是泛型

   一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----- 来源《Java编程思想》对泛型的介绍。
    泛型是在JDK1.5引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。


3.引出泛型

   假设我们要实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值。

  在我们以前学过的数组中,一种数组只能存放同一种的元素。例如 int[] array=new int[10];

  我们知道,所有类的父类都是Object类,那么我们可不可以定义一个Object类的数组呢?

让我们来试试看:

可以看到当我们存储不同的数据类型到我们的Object数组中的时候是可以的,但是当我们把它的值给String的时候,编译会报错,此时我们就只能进行强制类型转换,把它转换成String类型,才行。

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

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

    public static void main(String[] args) {
        MyArray<Integer> myArray=new MyArray<>();//2
        myArray.setVal(0,1);
        myArray.setVal(1,10);
        int a=myArray.getPos(0);//3
        System.out.println(a);
        myArray.setVal(2,"hello");//4
    }

}

代码解释:
1类名后的<E>代表占位符,表示当前类是一个泛型类

了解:【规范】类型形参一般使用一个大写字母表示,常用的名称有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
S, U, V 等等 - 第二、第三、第四个类型

2. 注释1处,不能new泛型类型的数组

E[] ts = new E[5];//是不对的

    但是这样来写并不是足够好,答案是未必的。这个问题我们一会来给大家介绍。

3. 注释2处,类型后加入 <Integer> 指定当前类型
4. 注释3处,不需要进行强制类型转换
5. 注释4处,代码编译报错,此时因为在注释2处指定类当前的类型,此时在注释4处,编译器会在存放元素的时候帮助我们进行类型检查。

4.泛型类的使用

4.1语法

泛型类<类型实参>变量名;//定义一个泛型类引用

new 泛型类<类型实参>(构造方法实参);实例化一个泛型类对象

  4.2示例

MyArray<Integer> list = new MyArray<Integer>();
注意:泛型只能接受类,所有的基本数据类型必须使用包装类

4.3类型推导

当编译器可以根据上下文推导出类型实参的时候,可以忽略类型实参的填写

MyArray<Integer> list = new MyArray<>(); // 可以推导出实例化需要的类型实参为 Integer     

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

5.泛型是如何编译的

5.1擦除机制

  那么,泛型到底是如何编译的呢?这个问题也是一个面试问题,泛型本质是一个很抽象的语法,要理解好它还是得需要一定的时间打磨。

  首先,我们要明白一件事,那就是泛型是一种编译的时候的机制,它在编译的时候会做两件事,第一件事是类型检查,检查我们存入的数据是否是我们在一开始所指定的类型,第二件事就是类型转换。

  在编译了以后,程序运行在jvm中了。我们要知道的是在jvm中是没有泛型的概念的。也就是说,泛型是一个编译机制,在编译完成以后,它仍然是一个Object。 

在编译的过程中,将所有的T都替换成Object的这种机制,我们称之为擦除机制。

5.2正确的写法

Java的泛型机制是在编译级别实现的,编译生成的字节码在运行期间并不会包含泛型的类型信息。
既然是这样,那么我们可不可以这样来定义一个泛型数组呢?

E[] array=new E[10];

它是否就等价于 Object[] array=new Object[10];

答案是不能,如果这样写的话,编译器会报错。 

我们来看看Java官方是如何来描述泛型的,打开ArraysList方法的源码看看

可以看到,在定义这些数组的时候,使用的是Object类型的数组,当我们使用的时候,我们来看看它的get方法                                                                                                                                                                                 

           

可以看到,定义的时候是Object类型的数组,但是在使用的时候,会强制类型转换为E类型。

6.泛型的上届

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

6.1语法

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

 6.2示例               

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

 只接受number的子类作为E的实例对象:

   

可以看到,当使用Integer类型的时候,是可以的。但是如果使用String类型就不行了。                                                                                             

注意:没有指定类型边界 E,可以视为 E extends Object
 

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

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

相关文章

腾讯云、阿里云、华为云便宜云服务器活动整理汇总

云服务器的选择是一个很重要的事情&#xff0c;避免产生不必要的麻烦&#xff0c;建议选择互联网大厂提供的云计算服务&#xff0c;腾讯云、阿里云、华为云就是一个很不错的选择&#xff0c;云服务器稳定性、安全性以及售后各方面都更受用户认可&#xff0c;下面小编给大家整理…

Kitchen Hook

双扛厨房排钩&#xff1a;挂刀具

linux 内存一致性

linux 出现内存一致性的场景 1、编译器优化 &#xff0c;代码上下没有关联的时候&#xff0c;因为编译优化&#xff0c;会有执行执行顺序不一致的问题&#xff08;多核单核都会出现&#xff09; 2、多核cpu乱序执行&#xff0c;cpu的乱序执行导致内存不一致&#xff08;多核出…

[二分查找] 旋转数组

1. &#xff08;严格递增序列&#xff09;旋转数组的元素查找 简单来说分为三种情况进行分析 1. 整个旋转数组单调递增 根据x和A[mid]的大小关系&#xff0c;更迭范围。 // 1. 整个旋转数组单调递增if (A[left]<A[right]){if (A[mid] x)return mid;else if (x < A[mid]…

C语言枚举类型enum详解、枚举变量。枚举函数

文章目录 枚举定义枚举应用枚举函数枚举函数2 枚举定义 关键字&#xff1a;enum 用途&#xff1a;定义一个取值受限制的整型变量&#xff0c;用于限制变量取值范围&#xff1b;宏定义的集合 定义枚举变量&#xff1a; enum{FALSE 0, TRUE 1} EnumName; 因为枚举变量类型较长…

矢量图片转换 Vector Magic for mac

Vector Magic会帮你进行自动识别和分析&#xff0c;转换过程中用户可选择相应的转换级别&#xff0c;从而达到自已所需的效果。 只需上传即可在线自动将 JPG、PNG、BMP 和 GIF 位图图像转换为真正的 SVG、Eps 和 PDF 矢量图像。真正的全彩描摹&#xff0c;无需安装软件&#xf…

java 对IP地址进行排序,或类ip地址的字符串进行排序

java 对IP地址进行排序&#xff0c;或类ip地址的字符串进行排序 排序前先认识一下这个拆分字符串非常好用的类 1.StringTokenizer类 1.1 构造方法 StringTokenizer(String str) &#xff1a;构造一个用来解析 str 的 StringTokenizer 对象。java 默认的分隔符是空格(“”)、…

PHP NBA球迷俱乐部系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP NBA球迷俱乐部系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 基于PHP的NBA球迷俱乐部 二、功能介绍 1、前台主要功能&#xff1a; 系统首页 网站介…

项目(补充2):智慧教室

一。emWin环境的搭建 1.codeBlock下载 开源免费。 2.使用stm的Cubemx提供的作图软件 &#xff08;1&#xff09;在C盘下找到第三方的固件库&#xff0c;旁边有个ST文件夹 注意&#xff1a;我在下载cubemx为默认的路径 &#xff08;2&#xff09;STemWin中的Soft提供了绘图…

【STM32】学习笔记(EXTI)

EXTI外部中断 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断优先级&#x…

字符串颜色

字体颜色 30&#xff1a;黑 31&#xff1a;红 32&#xff1a;绿 33&#xff1a;黄 34&#xff1a;蓝色 35&#xff1a;紫色 36&#xff1a;深绿 37&#xff1a;白色 字体背景颜色 40&#xff1a;黑 41&#xff1a;深红 42&#xff1a;绿 43&#xff1a;黄色 44&#xff1a;蓝…

使用 Tkinter 在 Python 中构建井字游戏!

一、说明 做你还记得小时候玩井字游戏吗&#xff1f;这是一个简单的游戏&#xff0c;只需一支笔或铅笔就可以在一张纸上玩。但是你知道你也可以使用Python的Tkinter库创建一个井字游戏吗&#xff1f;在本文中&#xff0c;我们将介绍使用 Tkinter 创建井字游戏的过程。在本文结束…

vue的 ECMAScript 6的学习

一 ECMAScript 6 1.1 ECMAScript 6 ECMAScript 和 JavaScript 的关系是&#xff0c;前者是后者的规格&#xff0c;后者是前者的一种实现&#xff08;另外的 ECMAScript 方言还有 Jscript 和 ActionScript&#xff09;。 因此&#xff0c;ES6 既是一个历史名词&#xff0c;也…

word添加字体库

1001 Fonts ❤ Free Fonts Baby!51044 free fonts in 28637 families Free licenses for commercial use Direct font downloads Mac Windows Linuxhttps://www.1001fonts.com/ 下载字体后复制粘贴到下面的位置&#xff1a;

IDEA自定义模板

IDEA自定义模板 &#xff08;1&#xff09;定义sop模板 ①在Live Templates中增加模板 ②先定义一个模板的组 ③在模板组里新建模板 ④定义模板 Abbreviation:模板的缩略名称Description:模板的描述Template text:模板的代码片段应用范围。比如点击Define。选择如下&…

输出图元(四)8-1 图元、屏幕坐标、指定二维世界坐标系统

用于图形应用的通用软件包称为计算机图形应用编程接口(CCAPI)它提供可以在C等程序设计语言中用来创建图形的函数库。如第3 章所指出的&#xff0c;函数库可以分成几种类型。创建图形时最先要做的一件事就是要描述显示场景的组成部分。图形的组成部分可以是树木和地形家具和墙壁…

无涯教程-JavaScript - CUBEKPIMEMBER函数

描述 该函数返回关键绩效指标(KPI)属性,并在单元格中显示KPI名称。 语法 CUBEKPIMEMBER (connection, kpi_name, kpi_property, [caption])争论 Argument描述Required/OptionalconnectionName of the connection to the cube - A text stringRequiredkpi_nameName of the K…

13. 性能测试

目录 1. 什么是性能测试 1.1 常见的性能问题 1.2 性能测试的概念 1.3 性能测试和功能测试的区别 1.4 性能的好坏如何定义 1.5 影响性能的因素 2. 为什么进行性能测试 3. 性能测试常见专业术语以及衡量指标 4. 性能测试分类 4.1 基准测试 4.2 负载测试 4.3 压力测…

FC-CLIP-卷积永存:开放词汇分割与单一冻结卷积CLIP

论文链接&#xff1a;https://arxiv.org/abs/2308.02487 Github&#xff1a;GitHub - bytedance/fc-clip: This repo contains the code for our paper Convolutions Die Hard: Open-Vocabulary Segmentation with Single Frozen Convolutional CLIP 机构&#xff1a;约翰霍普…

PLL原语例化使用时常见问题

目录 一、前言 二、常见问题 问题一、综合阶段报错[Synth 8-439] 问题二、综合阶段报错[Synth 8-448] 问题三、在实现阶段DRC报错DRC PDRC-38 问题四、在实现阶段DRC报错DRC PDRC-43 一、前言 在设计中经常会使用PLL的原语进行例化使用&#xff0c;PLL如果直接例化使用将…