数据结构系列二:包装类+泛型

包装类+泛型

  • 一、包装类
    • (1)基本数据类型和对应的包装类
    • (2)装箱和拆箱
  • 二、泛型
    • (1)什么是泛型
    • (2)引出泛型
    • (3)语法
    • (4)泛型类的使用
      • 1.语法
      • 2.示例
      • 3.类型推导
    • (5)裸类型
    • (6)泛型是如何编译的
      • 1.擦除机制
      • 2.为什么不能实例化泛型类数组?
    • (7)泛型的上界
      • 1.语法
      • 2.示例
      • 3.复杂示例
    • (8)泛型方法
      • 1.语法
      • 2.示例


一、包装类

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

(1)基本数据类型和对应的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
  • 除了Integercharacter,其余基本类型的包装类都是首字母大写

(2)装箱和拆箱

  • 装箱:把一个基本数据类型转化为包装类型的过程
  • 拆箱:将一个包装类中的值取出,放到一个基本类型中

自动装箱与自动拆箱

public class demo {public static void main(String[] args) {//自动装箱int i = 10;Integer a = i;//自动拆箱int b = a;}
}

显示装箱和显示拆箱

        //显示装箱int c = 20;Integer d = Integer.valueOf(c);//显示拆箱:拆箱为自己指定的元素int e = d.intValue();double e1 = d.doubleValue();

二、泛型

(1)什么是泛型

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

(2)引出泛型

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

  1. 我们以前学过的数组,只能存放指定类型的数据,例如String[]int[]
  2. 所有类的父类,默认为Object类,数组是否可以创建为Object
class MyArray{Object[] array = new Object[10];public void set(int pos,Object val){this.array[pos] = val;}public Object get(int pos){return this.array[pos];}
}
public class demo1 {public static void main(String[] args) {MyArray myArray = new MyArray();myArray.set(0,10000);myArray.set(1,"hello");String ret = myArray.get(1);//编译报错String ret = (String) myArray.get(1);}
}

以上代码实现后发现

  1. 任何类型数据都可以存放
  2. 1号下标本身就是字符串,但是却编译报错,必须进行强制类型转换才可以

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

(3)语法

class 泛型类名称<类型形参列表>{//这里可以使用类型参数
}
class ClassName<T1,T2……Tn>{}
class 泛型类名称<类型形参列表> extends 继承类{//这里可以使用类型参数
}
class ClassName<T1,T2……Tn> extends ParentClass<T1>{//可以只使用部分类型参数
}

上述代码进行改写如下

class Myarray<T>{Object[] array = new Object[10];public void set(int pos,T val){this.array[pos] = val;}public T get(int pos) {return (T)this.array[pos];}
}
public class demo2 {public static void main(String[] args) {Myarray<String> myArray = new Myarray<>();myArray.set(0,"sadfklsajdfs");myArray.set(1,"qwe");String ret = myArray.get(0);String ret1 = myArray.get(1);System.out.println(ret);System.out.println(ret1);Myarray<Integer> myarray = new Myarray<>();myarray.set(0,3);Integer ret2 = myarray.get(0);System.out.println(ret2);}
}
//输出结果
sadfklsajdfs
qwe
3Process finished with exit code 0

代码解释:

  1. 类名后的代表占位符,表示当前类是一个泛型类

类型形参一般使用一个大写字母来表示,常用的名称有

  • E表示Element
  • K表示Key
  • V表示Value
  • N表示Number
  • T表示Type
  1. 不能new泛型类型的数组
T[] ts = new T[5];//是不对的
  1. 类型后需要加入包装类指定当前类型
Myarray<String> myArray = new Myarray<>();
  1. 存放元素的时候会帮我们检查,如果和包装类不同,会报错提示

(4)泛型类的使用

1.语法

泛型类<类型实参> 变量名 = new 泛型类<类型实参>(构造方法实参);

2.示例

尖括号中只能是引用类型,不能是基本类型

Myarray<String> myArray = new Myarray<String>();

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

3.类型推导

当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写,但是尖括号不能省略

Myarray<String> myArray = new Myarray<>();

(5)裸类型

裸类型是一个泛型类但是没有带着类型实参

Myarray list = new Myarray();

注意:我们不要自己去使用裸类型,裸类型是为了兼容老版本的API保留的机制

(6)泛型是如何编译的

1.擦除机制

那么,泛型到底是怎么编译的呢?这个问题也是曾经的一个面试问题,泛型本质是一个非常难的语法,要理解好它还是需要一定的时间打磨
我们先察看字节码文件,发现所有的T都是Object

  • 在编译的过程中,将所有的T替换为Object这种机制,我们称为擦除机制
  • 运行的时候没有泛型这样的概念,泛型的擦除机制,只存在于编译期间

2.为什么不能实例化泛型类数组?

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

(7)泛型的上界

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

1.语法

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

2.示例

class test<E extends Number>{}

extends表示拓展,只接受Number的子类型作为E的类型实参

class test<E extends Number>{}
public class demo4 {public static void main(String[] args) {test<Integer> a1;//正常,因为Integer是Number的子类型test<String> a2;//编译错误,因为String不是Number的子类型}
}

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

3.复杂示例

写一个泛型类,实现一个方法,这个方法是就指定类型泛型的最大值

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 demo5 {public static void main(String[] args) {Alg<Integer> alg1 = new Alg<>();Integer[] array = {1,2,3,4,5};Integer ret = alg1.findMax(array);System.out.println(ret);}
}
//输出结果
5Process finished with exit code 0

(8)泛型方法

1.语法

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

2.示例

class Util{public <T extends Comparable<T>> 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 demo6 {public static void main(String[] args) {Util util = new Util();Integer[] array = {1,2,3,4,5};Integer ret = util.findMax(array);System.out.println(ret);}
}
//输出结果
5Process finished with exit code 0

静态方法可以直接通过类名调用

class Util{public static <T extends Comparable<T>> 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 demo6 {public static void main(String[] args) {Integer[] array = {1,2,3,4,5};Integer ret = Util.findMax(array);System.out.println(ret);}
}
//输出结果
5Process finished with exit code 0

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

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

相关文章

量子计算驱动的金融衍生品定价革命:突破传统蒙特卡洛模拟的性能边界

引言&#xff1a;金融计算的算力困局 某国际投行采用128量子位处理器对亚洲期权组合定价时&#xff0c;其量子振幅估计算法在2.7秒内完成传统GPU集群需要68小时的计算任务。在蒙特卡洛路径模拟实验中&#xff0c;量子随机游走算法将10,000维衍生品的价格收敛速度提升4个数量级…

Spring容器初始化扩展点:ApplicationContextInitializer

目录 一、什么是ApplicationContextInitializer&#xff1f; 1、核心作用2、适用场景 二、ApplicationContextInitializer的使用方式 1、实现ApplicationContextInitializer接口2、注册初始化器 三、ApplicationContextInitializer的执行时机四、实际应用案例 1、动态设置环境…

hive—常用的函数整理

1、size(split(...))函数用于计算分割后字符串数组的长度 实例1&#xff09;&#xff1a;由客户编号列表计算客户编号个数 --数据准备 with tmp_test01 as ( select tag074445270 tag_id,202501busi_mon , 012399931003,012399931000 index_val union all select tag07444527…

vue3 采用xlsx库实现本地上传excel文件,前端解析为Json数据

需求&#xff1a;本地上传excel 文件&#xff0c;但需要对excel 文件的内容进行解析&#xff0c;然后展示出来 1. 安装依赖 首先&#xff0c;确保安装了 xlsx 库&#xff1a; bash复制 npm install xlsx 2. 创建 Vue 组件 创建一个 Vue 组件&#xff08;如 ExcelUpload.v…

若依框架实现动态失效时间JWT Token的实践指南

一、功能需求背景 在前后端分离架构中&#xff0c;JWT&#xff08;JSON Web Token&#xff09;作为无状态认证方案被广泛使用。若依&#xff08;RuoYi&#xff09;框架的TokenService默认采用固定失效时间策略&#xff0c;但在实际开发中常需要根据业务场景动态调整Token有效期…

C++ 设计模式-策略模式

支付策略 #include <iostream> #include <memory> #include <unordered_map> #include <vector> #include <ctime>// 基础策略接口 class PaymentStrategy { public:virtual ~PaymentStrategy() default;virtual std::string name() const 0;…

国产编辑器EverEdit - 如何在EverEdit中管理工程?

1 工程管理 1.1 应用场景 用户创建工程后&#xff0c;会涉及到工程的管理 &#xff0c;比如&#xff1a;打开工程、关闭工程等 1.2 使用方法 1.2.1 打开工程 单击主菜单工程 -> 打开工程&#xff0c;会弹出打开对话框&#xff0c;用户在对话框中选择需要打开的工程文件即…

MYSQL-数据库-DDL-DML-DQL-DCL-基础学习

MySql概念&#xff1a; 建立在关系模型基础上&#xff0c;有多张相互连接的二维表组成的数据库 SQL通用语法&#xff1a; 1.SQL语句可以单行或多行书写&#xff0c;以分号结尾 2.SQL语句可以使用空格/缩进来增强语句的可读性 3.MySQL数据库的SQL语句不区分大小写&#xff0c;关…

SpringBoot核心框架之AOP详解

SpringBoot核心框架之AOP详解 一、AOP基础 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程&#xff0c;面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 场景&#xff1a;项目部分功能运行较慢&#xff0c;定位执行耗时…

【RK3588嵌入式图形编程】-SDL2-构建模块化UI

构建模块化UI 文章目录 构建模块化UI1、概述2、创建UI管理器3、嵌套组件4、继承5、多态子组件6、总结在本文中,将介绍如何使用C++和SDL创建一个灵活且可扩展的UI系统,重点关注组件层次结构和多态性。 1、概述 在前面的文章中,我们介绍了应用程序循环和事件循环,这为我们的…

第四届图像、信号处理与模式识别国际学术会议(ISPP 2025)

重要信息 会议官网&#xff1a;www.icispp.com 会议时间&#xff1a;2025年3月28-30日 会议地点&#xff1a;南京 简介 由河海大学和江苏大学联合主办的第四届图像、信号处理与模式识别国际学术会议&#xff08;ISPP 2025) 将于2025年3月28日-30日在中国南京举行。会议主…

低代码与开发框架的一些整合[2]

1.分析的项目资源说明 经过近期的的不断分析与运行对比&#xff0c;最终把注意力集中在了以下几个框架&#xff1a; 01.dibootdiboot.diboot: 写的更少, 性能更好 -> 为开发人员打造的低代码开发平台。Mybatis-plus关联查询&#xff0c;关联无SQL&#xff0c;性能高10倍&a…

Spring Boot 中事务的用法详解

引言 在 Spring Boot 中&#xff0c;事务管理是一个非常重要的功能&#xff0c;尤其是在涉及数据库操作的业务场景中。Spring 提供了强大的事务管理支持&#xff0c;能够帮助我们简化事务的管理和控制。本文将详细介绍 Spring Boot 中事务的用法&#xff0c;包括事务的基本概…

Java面试——Tomcat

优质博文&#xff1a;IT_BLOG_CN 一、Tomcat 顶层架构 Tomcat中最顶层的容器是Server&#xff0c;代表着整个服务器&#xff0c;从上图中可以看出&#xff0c;一个Server可以包含至少一个Service&#xff0c;用于具体提供服务。Service主要包含两个部分&#xff1a;Connector和…

第4章 信息系统架构(三)

4.3 应用架构 应用架构的主要内容是规划出目标应用分层分域架构&#xff0c;根据业务架构规划目标应用域、应用组和目标应用组件&#xff0c;形成目标应用架构逻辑视图和系统视图。从功能视角出发&#xff0c;阐述应用组件各自及应用架构整体上&#xff0c;如何实现组织的高阶…

python小项目编程-中级(1、图像处理)

目录 图像处理 实现 测试 unittest pytest 图像处理 实现界面化操作&#xff0c;使用PIL库实现简单的图像处理功能&#xff0c;如缩放&#xff08;设置缩放比例&#xff09;、旋转和滤镜、对比度调整、亮度调整、灰度图、二值化图&#xff08;二值图如果使用的是彩色图片需…

【Leetcode 每日一题】2209. 用地毯覆盖后的最少白色砖块

问题背景 给你一个下标从 0 0 0 开始的 二进制 字符串 f l o o r floor floor&#xff0c;它表示地板上砖块的颜色。 f l o o r [ i ] floor[i] floor[i] 为 ‘0’ 表示地板上第 i i i 块砖块的颜色是 黑色 。 f l o o r [ i ] floor[i] floor[i] 为’1’ 表示地板上第 i …

Docker 性能优化指南

Docker 提供了强大的容器化功能&#xff0c;能够帮助开发者在不同的环境中构建、测试和部署应用。然而&#xff0c;随着容器化应用的不断增长&#xff0c;Docker 容器可能会面临一些性能瓶颈&#xff0c;影响其运行效率、资源占用和扩展能力。为了确保容器在生产环境中的高效运…

2025 WE DAY品牌日| 天璇II WE X7 Pro充电桩震撼发布,能效电气开启充电革命

随着新能源产业的迅猛发展,充电桩作为电动汽车能量补给的重要基础设施,正在成为市场关注的焦点。能效电气作为充电桩领域的佼佼者,专注于研发高效、智能的充电解决方案,为电动汽车的普及与可持续发展铺设了坚实的基础。 2025年2月21日,能效电气在深圳盛大举办了以“以创新 引未…

< OS 有关 > Ubuntu 24 SSH 服务器更换端口 in jp/us VPSs

原因&#xff1a; 两台 VPS 的 ssh 端口一直被密码重试&#xff0c; us 这台已经封了 632, jp 这台两周前清过一次 sqlite3 数据&#xff0c;现在赞到 1008 Fail2Ban 是使用 sqlite3 来记录&#xff0c;数据量大后&#xff0c;硬盘的 I/O 会飙升&#xff0c;我有写过一个 app…