当前位置: 首页 > news >正文

数据结构(Java)—— 认识泛型

1. 包装类

  在学习泛型前我们需要先了解一下包装类

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

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

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

1.2 装箱和拆箱

装箱是把基本类型变成包装类型,拆箱就是把包装类型变成基本类型。

代码示例如下:

int i = 10;
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ii = Integer.valueOf(i);
Integer ij = new Integer(i);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = ii.intValue()
可以看到在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担, java 提供了自动机制。
代码示例如下:
int i = 10;
Integer ii = i; // 自动装箱
Integer ij = (Integer)i; // 自动装箱
int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱

注意

1. 在Integer这个包装类型中,取得值如果在-128~127 之间可直接进行比较,超过这个范围后Integer 会new 一个数值,这时就进行不了比较。

2. 除了 Integer Character, 其余基本类型的包装类都是首字母大写。

2.泛型 

2.1 概念

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

2.2 语法

1. 泛型类 < 类型实参 > 变量名 ; // 定义一个泛型类引用
class 泛型类名称 < 类型形参列表 > {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > {
}
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
// 可以只使用部分类型参数
}
2. new 泛型类 < 类型实参 > ( 构造方法实参 ); // 实例化一个泛型类对象

举例说明:实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值。

class MyArray<T> {//1. 类名后的 <T> 代表占位符,表示当前类是一个泛型类public T[] array = (T[])new Object[10];//2.不能new泛型类型的数组public T getPos(int pos) {return this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}
public class test{public static void main(String[] args) {MyArray<Integer> myArray = new MyArray<>();//3.类型后加入 <Integer> 指定当前类型myArray.setVal(0,10);myArray.setVal(1,12);int ret = myArray.getPos(1);//4.不需要进行强制类型转换System.out.println(ret);// myArray.setVal(2,"bit");//5.代码编译报错,此时因为在注释2处指定类当前的类型,此时在注释4处,编译器会在存放元素的时//候帮助我们进行类型检查}
}

 运行结果如下:

注意:
1. 泛型只能接受类,所有的基本数据类型必须使用包装类!
2.   【规范】类型形参一般使用一个大写字母表示,常用的名称有:
  • E 表示 Element
  • K 表示 Key
  • V 表示 Value
  • N 表示 Number
  • T 表示 Type
  • S, U, V 等等 - 第二、第三、第四个类型

2.3 类型推导

当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写,例如:
MyArray < Integer > list = new MyArray <> (); // 可以推导出实例化需要的类型实参为 Integer

3. 裸类型

裸类型是一个泛型类但没有带着类型实参,例如 MyArrayList 就是一个裸类型
MyArray list = new MyArray ();
注意: 我们不要自己去使用裸类型,裸类型是为了兼容老版本的 API 保留的机制
小结:
1. 泛型是将数据类型参数化,进行传递
2. 使用 <T> 表示当前类是一个泛型类。
3. 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换

4. 编译——擦除机制

通过命令:javap -c 查看字节码文件,所有的T都是Object

在编译的过程当中,将所有的 T 替换为 Object 这种机制,我们称为: 擦除机制
Java 的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。
注意:
1. 不能实例化泛型类型数组,虽然 Object 是所有类的父类,在编译的过程当中T替换为Object,但是Object[] 不是 所有数组的父类。

原因:替换后的方法为:将Object[]分配给Integer[]引用,程序报错。 通俗讲就是:返回的Object数组里面,可能存放的是任何的数据类型,可能是String,可能是Person,运行的时候,直接转给Integer类型的数组,编译器认为是不安全的。

2.Java中的类型擦除并不总是把类参数 T 替换成Object,而是根据泛型边界和通配符的使用情况将其替换成相应的类或接口。这种机制使得Java的泛型在编译时提供类型安全,同时在运行时保持与Java 1.5之前的版本兼容。

5. 泛型的上界

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

5.1 语法

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

5.2 示例

示例一:代码如下:

class MyArray<E extends Number> {}
public class test {public static void main(String[] args) {MyArray<Integer> myArray1 ;// MyArray<String> myArray2;}
}

运行结果如下:

示例二:定义一个泛型类 ,找到数组中的最大值

代码如下:

class Alg<T extends Comparable<T>>{public T findMax(T[] array){T max = array[0];for (int i = 1; i < array.length; i++) {if (array[i].compareTo(max) > 0) {max = array[i];}}return max;}
}
public class test {public static void main(String[] args) {Alg<Integer> alg= new Alg<>();Integer[] arr = {1,2,3,4,5,6,7};System.out.println(alg.findMax(arr));}
}

运行结果如下:

6. 泛型方法

6.1 定义语法

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

6.2 示例

示例一:

代码如下:

//静态的泛型方法 需要在static后用<>声明泛型类型参数
public static <E> void swap(E[] array, int i, int j) {
E t = array[i];
array[i] = array[j];
array[j] = t;
}

示例二:使用类型推导

 

示例三:不使用类型推导

本文是作者学习后的总结,如果有什么不恰当的地方,欢迎大佬指正!!!

相关文章:

数据结构(Java)—— 认识泛型

1. 包装类 在学习泛型前我们需要先了解一下包装类 在 Java 中&#xff0c;由于基本类型不是继承自 Object &#xff0c;为了在泛型代码中可以支持基本类型&#xff0c; Java 给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 基本数据类型包装类byteByt…...

处理后的视频如何加上音频信息?

总方案:原来模型对图像进行每帧处理,保留后的视频自然失去了audio信息,因此先用ffmpeg处理得到audio,原输出video加上audio即可,也采用ffmpeg处理。 imageio库用于读取和写入视频文件,并且你正在使用img_cartoon模型处理每一帧图像。然而,这段代码只处理了视频的图像部…...

02LangChain 实战课——安装入门

LangChain安装入门 一、大语言模型简介 大语言模型是利用深度学习技术&#xff0c;尤其是神经网络&#xff0c;来理解和生成人类语言的人工智能模型。这些模型因其庞大的参数数量而得名&#xff0c;能够理解和生成复杂的语言模式。它们通过预测下一个词来训练&#xff0c;基于…...

Python函数中关键字参数、位置参数、默认参数有何不同

在Python中&#xff0c;函数的参数分为三种类型&#xff1a;关键字参数&#xff08;key arguments&#xff09;、位置参数&#xff08;positional arguments&#xff09;和默认参数&#xff08;default arguments&#xff09;。它们的主要区别在于调用时如何传递值&#xff0c;…...

PNG 格式和 JPG 格式都什么时候用

通常我们都知道&#xff0c;如果是针对网络传输或者网站的格式&#xff0c;我们多会使用 PNG 格式。 如果是照片&#xff0c;大部分都是 JPG 格式的。 那么我们网站常用的截图应该保存为什么格式呢&#xff1f; 照片截图 照片截图应该保存为 JPG 格式。 虽然现在我们多存储…...

Qt 练习做一个登录界面

练习做一个登录界面 效果 UI图 UI代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Dialog</class><widget class"QDialog" name"Dialog"><property name"ge…...

计算机视觉实验一:图像基础处理

1. 图像的直方图均衡 1.1 实验目的与要求 (1)理解直方图均衡的原理与作用; (2)掌握统计图像直方图的方法; (3)掌握图像直方图均衡的方法。 1.2 实验原理及知识点 直方图均衡化是通过灰度变换将一幅图象转换为另一幅均衡直方图&#xff0c;即在每个灰度级上都具有相同的象素…...

【WebApi】C# webapi 后端接收部分属性

在C#的Web API后端接收部分属性,可以使用[FromBody]特性配合JsonPatchDocument或者Delta来实现。这里提供一个使用JsonPatchDocument的示例。 首先,定义一个模型类:public class User public class User {public int Id {get; set; }...

Java 使用 Redis

Java 使用 Redis 1. 引言 Redis是一个开源的、基于内存的数据结构存储系统,可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串、哈希、列表、集合、有序集合等。由于Redis基于内存,其读写速度非常快,因此被广泛应用于需要高速缓存和实时通讯的场景。…...

【ONE·Linux || 高级IO(二)】

总言 主要内容&#xff1a;多路转接&#xff1a;epoll学习。       文章目录 总言5、多路转接&#xff1a;epoll5.1、相关概念与接口5.1.1、基本函数认识5.1.1.1、epoll_create5.1.1.2、epoll_ctl5.1.1.3、epoll_wait 5.1.2、epoll的工作原理5.1.2.1、准备工作&#xff08;…...

将 IBM WatsonX 数据与 Milvus 结合使用,构建用于知识检索的智能 Slack 机器人

在当今快节奏的工作环境中&#xff0c;快速轻松地访问信息对于保持生产力和效率至关重要。无论是在 Runbook 中查找特定说明&#xff0c;还是访问关键知识转移 &#xff08;KT&#xff09; 文档&#xff0c;快速检索相关信息的能力都可以产生重大影响。 本教程将指导您构建一个…...

2024 网鼎杯 CTF --- Crypto wp

文章目录 青龙组Crypto1Crypto2 白虎组Crypto1Crypto2 朱雀组Crypto2Crypto3part1part2part3part4 青龙组 Crypto1 题目&#xff1a; from Crypto.Util.number import * from secret import flagp getPrime(512) q getPrime(512) n p * q d getPrime(299) e inverse(d,…...

深度学习基础知识-损失函数

目录 1. 均方误差&#xff08;Mean Squared Error, MSE&#xff09; 2. 平均绝对误差&#xff08;Mean Absolute Error, MAE&#xff09; 3. Huber 损失 4. 交叉熵损失&#xff08;Cross-Entropy Loss&#xff09; 5. KL 散度&#xff08;Kullback-Leibler Divergence&…...

《逆向记录》

这里写自定义目录标题 1.什么是vmp加密VMP加密的工作原理VMP加密的应用场景和优缺点实际应用案例 2.什么是ast混淆3.魔改算法总结 1.什么是vmp加密 ‌VMP加密&#xff08;Virtual Machine Protection&#xff09;‌是一种软件保护技术&#xff0c;旨在通过虚拟化和加密技术来保…...

chatgpt3.5权重参数有多少MB;llama7B权重参数有多少MB

目录 chatgpt3.5权重参数有多少MB llama7B权重参数有多少MB chatgpt3.5权重参数有多少MB 关于ChatGPT 3.5的权重参数占用的存储空间大小,虽然直接给出具体的MB数值可能较为困难(因为这取决于多种因素,如参数表示的精度、是否进行了压缩等),但可以根据其参数量来估算一个…...

ST IoT Wireless 物联网与无线技术 研讨会

一、研讨会背景与目的 ◆ 意法半导体致力于提供可靠且经济实惠的无线连接解决方案,包含Wireless NFC Security & Esim等产品。 ◆ 将智能物体连接到互联网和云&#xff0c;或者从更广泛的意义上说&#xff0c;连接到物联网&#xff08;IoT&#xff09;。 ◆ 远程监控、配…...

PHP实现雪花算法生成唯一ID

引言 雪花算法是Twitter开源的分布式ID生成算法&#xff0c;可以产生64位的ID。其中第一位是固定的正数标识&#xff0c;41位用于存储时间戳&#xff0c;剩下的为机器ID和序列号。通过时间戳、机器ID和序列号的组合&#xff0c;确保每个ID都是唯一的。 PHP代码 1、定义雪花算…...

APP的设置页面,应该怎样尽可能减少用户的输入操作呢

一、引言 在当今数字化时代&#xff0c;移动应用程序&#xff08;APP&#xff09;已经成为人们生活中不可或缺的一部分。无论是社交娱乐、工作学习还是日常生活&#xff0c;我们都离不开各种 APP 的帮助。而 APP 的设置页面作为用户调整应用参数、个性化定制功能的重要入口&am…...

Node.js:内置模块

Node.js&#xff1a;内置模块 Node.jsfs模块读取文件写入文件__dirname path模块路径拼接文件名解析 http模块创建服务 Node.js 传统的JavaScript是运行在浏览器的&#xff0c;浏览器就是其运行环境。 浏览器提供了JavaScript的API&#xff0c;以及解析JavaScript的解析引擎&a…...

3. keil + vscode 进行stm32协同开发

1. 为什么使用vscode 主要还是界面友好&#xff0c;使用习惯问题&#xff0c;vscode 从前端&#xff0c;js, c/c, qt, 仓颉&#xff0c;rust都有很好插件的支持&#xff0c;并且有romote&#xff0c; wsl 等很多插件可以提高效率&#xff0c; 唯一的问题就是要使用插件进行环境…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

如何把工业通信协议转换成http websocket

1.现状 工业通信协议多数工作在边缘设备上&#xff0c;比如&#xff1a;PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发&#xff0c;当设备上用的是modbus从站时&#xff0c;采集设备数据需要开发modbus主站&#xff1b;当设备上用的是西门子PN协议时&#xf…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...