数据结构:包装类和泛型

目录

一、包装类

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

 2、装箱和拆箱 

3、自动装箱和自动拆箱 

二、泛型 

1、什么是泛型

2、泛型语法 

3、泛型类 

4、擦除机制 

5、泛型的上界 

6、泛型方法

三、通配符 

1、什么是通配符 

2、通配符上界 

3、通配符下界 


📚一、包装类

包装类是对应着各种基本数据类型进行包装后产生的引用数据类型,我们甚至可以称它们为基本数据类型的plus版本。

至于我们为什么要设计包装类这是因为Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类

🐬1、基本数据类型和对应的包装类

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

🐬 2、装箱和拆箱 

 int i = 10;
//装箱操作,新建⼀个Integer 类型对象,将i 的值放⼊对象的某个属性中Integer ii = Integer.valueOf(i);Integer ij = new Integer(i);//拆箱操作,将Integer 对象中的值取出,放到⼀个基本数据类型中int j = ii.intValue();

然而我们发现在使用过程中这种装箱和拆箱的过程,带了不少的代码量,于是为了减少开发时的负担,java提供了自动装箱和拆箱机制。

🐬3、自动装箱和自动拆箱 

public class  Test{public static void main(String[] args) {int i = 10;Integer ii = i;//⾃动装箱Integer ij = (Integer)i;//⾃动装箱int j = ii;//⾃动拆箱int k = (int)ii;//⾃动拆箱}
}

我们可以发现这种自动的装箱和拆箱方式大大的减少了我们的代码量和开发负担 

现在我们已经大致了解了包装类了,接下来让我们来看一道题

public class  Test{public static void main(String[] args) {Integer a = 127;Integer b = 127;Integer c = 128;Integer d = 128;System.out.println(a == b);System.out.println(c == d);}
}

他的输出结果是什么呢?可能我们下意识认为都是true,但我们看一下运行后给出的结果 

我们发现并不都是true这是为什么呢?

首先我们先来了解一下“==”“==”在比较基本数据类型的时候,就是字面值的比较,而现在我们并不是基本数据类型,而是由基本类型转变的包装类属于引用类型,而“==” 在比较引用类型的时候,比较的是地址,但是由于Integer是具有范围的-128~127,在这区间的值是被存放在常量池中,所以只有是处于这个区间的相同值进行比较都是相同的,但是128超出了这个范围,因此两个变量的值虽然都等于128,但并不是同一个地址,因此不为true。

📚二、泛型 

🐬1、什么是泛型

一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。

因此我们在JDK1.5引入的新的语法:泛型,所谓泛型就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化

我们来看这样一个例子,在数组中存放各种类型的元素

我们知道Object类默认为所有类的父类,所以我们创建的数组为Object类的数组。

创建完后我们发现的确任何的类型我们都能够进行存放了,但是当我们进行元素的取出时我们发现,编译器进行了报错,这时因为我们要取出的虽然本身是字符串,但是我们必须进行强制类型转换。

但是,更多情况下,我们还是希望他只能够持有一种数据类型。而不是同时持有这么多类型。所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象,让编译器去做检查。 

🐬2、泛型语法 

基础写法:

class 泛型类名称 < 类型形参列表 > {// 这里可以使用类型参数}class ClassName<T1,T2,T3,...,Tn>{}

其他写法: 

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

因此我们就可以将上述代码写成新的样子 

class MyArray1<T> {public Object[] array = new Object[10];//public T[] array = (T[]) new Object[10];两种写法都可以public T getPos(int pos) {return (T)this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}
public class TestDemo1 {public static void main(String[] args) {MyArray1<Integer> myArray1 = new MyArray1<>();myArray1.setVal(0,10);int ret1 = myArray1.getPos(0);System.out.println(ret1);MyArray1<String> myArray2 = new MyArray1<>();myArray2.setVal(0,"hello");String ret2 = myArray2.getPos(0);System.out.println(ret2);}
}

 

我们发现利用这种方法我们就可以吧不同类型的相同操作只利用一段代码并在主函数中传入不同的类型就可全部使用,这就是我们使用泛型的原因。

当然泛型还是有一些规范的

  1. 类名后的<T>代表占位符,表示当前类是一个泛型类
  2. 类型形参一般使用一个大写字母表示,常用的名称有:
  • E表示Element
  • K表示Key
  • V表示Value 
  • N表示Number
  • T表示Type
  • S,U,V等等-第二、第三、第四个类型

🐬3、泛型类 

泛型类<类型实参> 变量名;        // 定义⼀个泛型类引⽤new 泛型类<类型实参>(构造⽅法实参);        //实例化⼀个泛型类对象MyArray<Integer> list = new MyArray<Integer>();当编译器可以根据上下⽂推导出类型实参时,可以省略类型实参的填写MyArray<Integer> list = new MyArray<>();

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

🐬4、擦除机制 

现在我们已经大致了解了泛型的用法了,但是大家有没有想过泛型是怎么在编译器上进行编译的呢,而这就涉及到了我们的擦除机制

  1. 在编译时,Java编译器会将泛型类型信息从代码中移除,这个过程就叫做类型擦除。
  2. 擦除后,泛型类型会被替换为其边界类型(通常是Object)或者指定的类型。

擦除过程

  1. 将泛型参数替换为其边界或Object
  2. 在必要的地方插入类型转换以保持类型安全。
  3. 生成桥接方法以保持多态性。 

 

🐬5、泛型的上界 

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

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

而类型边界中所谓的上界,其实就是代表我们规定的边界作为父类,而我传入的变量必须是父类本身或者是父类的子类

例如Number的子类有Integer,没有String

public class MyArray<E extends Number> {...
}MyArray<Integer> l1;//正常,因为Integer是Number的⼦类型MyArray<String> l2;//编译错误,因为String不是Number的⼦类型

对于接口也是一样的

 // E必须是实现了Comparable接⼝的
public class MyArray<E extends Comparable<E>> {...}

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

🐬6、泛型方法

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

 例子:交换元素

📚三、通配符 

🐬1、什么是通配符 

? 用于在泛型的使用,即为通配符

我们发现相同类型的引用是可以相互指向的,而不同类型的引用是不能相互指向的,那么我们可不可建立一个能够指向多种不同泛型参数的对象呢?这就需要用到我们的通配符了 

我们发现当我们使用了通配符?之后就可以指向不同的泛型参数了 。

当然,有些时候我们同样希望它能够像泛型一样只指向像一部分的泛型参数,所以这时我们在通配符上也引用了上界,同时通配符多了一项对下界的限制

? extends 类:设置通配符上限

? super 类:设置通配符下限

🐬2、通配符上界 

 <? extends 上界> 
<? extends Number>//可以传⼊的实参类型Number或者Number的⼦类

 跟泛型的上界一样,同样将通配符限制为界限的本身和他的子类

🐬3、通配符下界 

 <? super 下界> 
<? super Integer>//代表可以传⼊的实参的类型是Integer或者Integer的⽗类类型

而下界则是,通配符的范围只能界限的本身和他的父类


好了今天的分享就到这里,还请大家多多关注,我们下一篇见! 

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

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

相关文章

备考蓝桥杯:顺序表相关算法题

目录 询问学号 寄包柜 移动0 颜色分类 合并两个有序数组 物品移动 询问学号 我们的思路&#xff1a;创建一个顺序表存储从1开始依次存放进入教室的学生学号&#xff0c;然后查询 #include <iostream> #include <vector> using namespace std; const int N 2…

Python入门教程 —— 网络编程

1.网络通信概念 简单来说,网络是用物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的。 使用网络的目的,就是为了联通多方然后进行通信,即把数据从一方传递给另外一方。 前面的学习编写的程序都是单机的,即不能和其他电脑上的程…

C#异步多线程——ThreadPool线程池

C#实现异步多线程的方式有多种&#xff0c;以下总结的是ThreadPool的用法。 线程池的特点 线程池受CLR管理&#xff0c;线程的生命周期&#xff0c;任务调度等细节都不需要我们操心了&#xff0c;我们只需要专注于任务实现&#xff0c;使用ThreadPool提供的静态方法把我们的任…

68.基于SpringBoot + Vue实现的前后端分离-心灵治愈交流平台系统(项目 + 论文PPT)

项目介绍 本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述心灵治愈交流平台的当前背景以及系统开发的目的&#xff0c;后续章节将严格按照软件开发流程&#xff0c;对系统进…

Linux(上):基本知识篇

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Linux初识1 Linux简介2 Linux学习环境配置(1)安装Linux(2)FinalShell远程连接Linux服务器二、Linux基础命令1 Linux目录结构,根目录 /2 Linux命令基础(1)什么是命令、命令行?(2)…

Python中的可变对象与不可变对象;Python中的六大标准数据类型哪些属于可变对象,哪些属于不可变对象

Python中的可变对象与不可变对象&#xff1b;Python中的六大标准数据类型哪些属于可变对象&#xff0c;哪些属于不可变对象 Python中的可变对象与不可变对象一、Python的六大标准数据类型1. 数字类型 (Number)2. 字符串 (String)3. 列表 (List)4. 元组 (Tuple)5. 集合 (Set)6. …

VSCode Live Server 插件安装和使用

VSCode Live Server是一个由Ritwick Dey开发的Visual Studio Code扩展插件&#xff0c;它提供了一个带有实时重载功能的本地开发服务器。在VSCode中安装和使用Live Server插件进行实时预览和调试Web应用程序。这将大大提高前端开发效率&#xff0c;使网页设计和开发变得更为流畅…

Personal APP

1、Matlab 2023b https://www.bilibili.com/opus/887246540317392920 https://blog.csdn.net/qq_25719943/article/details/138096918 https://www.jokerdown.com/22886.html 2、Jlink使用技巧 J-Scope虚拟示波器功能 Jlink使用技巧之J-Scope虚拟示波器功能 - 知乎 (zhihu.…

【马来西亚理工大学主办,ACM出版】2025年大数据、通信技术与计算机应用国际学术会议(BDCTA 2025)

2025年大数据、通信技术与计算机应用国际学术会议&#xff08;BDCTA 2025) 2025 International Conference on Big Data, Communication Technology and Computer Applications 2025年2月14-16日 | 马来西亚-吉隆坡 大会官网&#xff1a;更多详情【论文投稿】 主办单位&…

Sprint Boot教程之五十:Spring Boot JpaRepository 示例

Spring Boot JpaRepository 示例 Spring Boot建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是一个基…

超完整Docker学习记录,Docker常用命令详解

前言 关于国内拉取不到docker镜像的问题&#xff0c;可以利用Github Action将需要的镜像转存到阿里云私有仓库&#xff0c;然后再通过阿里云私有仓库去拉取就可以了。 参考项目地址&#xff1a;使用Github Action将国外的Docker镜像转存到阿里云私有仓库 一、Docker简介 Do…

左神算法基础巩固--3

文章目录 二叉树二叉树的遍历先序遍历中序遍历后序遍历 解答二叉树的宽度优先遍历 在这里插入图片描述 一颗完全二叉树具有以下特征&#xff1a;1.不存在任何一个节点具有右子树但不存在左子树.2.不存在任何一个节点在满足1的情况下左右子树不全且其后续节点不为叶子节点 根据以…

推动多语言语音科技迈向新高度:INTERSPEECH 2025 ML-SUPERB 2.0 挑战赛

随着语音技术在各领域应用的迅速扩展&#xff0c;全球语言与口音的多样性成为技术进一步突破的重大挑战。为了应对这一难题&#xff0c;来自卡内基梅隆大学&#xff08;CMU&#xff09;、斯坦福大学&#xff08;Stanford University&#xff09;、乔治梅森大学(George Mason Un…

IvorySQL 升级指南:从 3.x 到 4.0 的平滑过渡

日前&#xff0c;IvorySQL 4.0 重磅发布&#xff0c;全面支持 PostgreSQL 17&#xff0c;并且增强了对 Oracle 的兼容性。关于 IvorySQL 4.0 的介绍&#xff0c;各位小伙伴可以通过这篇文章回顾&#xff1a;IvorySQL 4.0 发布&#xff1a;全面支持 PostgreSQL 17. 在 IvorySQL…

flink的EventTime和Watermark

时间机制 Flink中的时间机制主要用在判断是否触发时间窗口window的计算。 在Flink中有三种时间概念&#xff1a;ProcessTime、IngestionTime、EventTime。 ProcessTime&#xff1a;是在数据抵达算子产生的时间&#xff08;Flink默认使用ProcessTime&#xff09; IngestionT…

Windows11环境下设置MySQL8字符集utf8mb4_unicode_ci

1.关闭MySQL8的服务CTRLshiftESC&#xff0c;找到MySQL关闭服务即可 2.找到配置文件路径&#xff08;msi版本默认&#xff09; C:\ProgramData\MySQL\MySQL Server 8.0 3.使用管理员权限编辑my.ini文件并保存 # Other default tuning values # MySQL Server Instance Config…

python学习笔记—14—函数

1. 函数 (1) len与my_len str "supercarrydoinb"def my_len(tmp_str):cnt 0for i in tmp_str:cnt 1return cntstr_len_1 len(str) str_len_2 my_len(str) print(f"len {str_len_1}") print(f"my_len {str_len_2}") (2) 函数传参数量不受…

Flink源码解析之:Flink on k8s 客户端提交任务源码分析

Flink on k8s 客户端提交任务源码分析 当我们需要在代码中提交Flink job到kubernetes上时&#xff0c;需要如何做呢&#xff1f;要引入什么第三方依赖&#xff1f;需要提供什么内容&#xff1f;flink是如何将job提交到k8s上的&#xff1f;经过了什么样的流程&#xff0c;内部有…

React Native 项目 Error: EMFILE: too many open files, watch

硬件&#xff1a;MacBook Pro (Retina, 13-inch, Mid 2014) OS版本&#xff1a;MacOS BigSur 11.7.10 (20G1427) 更新: 删除modules的方法会有反弹&#xff0c;最后还是手动安装了预编译版本的watchman。 React Native 项目运行npm run web&#xff0c;出现如下错误&#xff1a…

51单片机——定时器中断(重点)

STC89C5X含有3个定时器&#xff1a;定时器0、定时器1、定时器2 注意&#xff1a;51系列单片机一定有基本的2个定时器&#xff08;定时器0和定时器1&#xff09;&#xff0c;但不全有3个中断&#xff0c;需要查看芯片手册&#xff0c;通常我们使用的是基本的2个定时器&#xff…