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

数据结构预备知识(Java):包装类泛型

1、包装类

1.1 包装类

在Java中,每一个基本数据类型都有一个对应的包装类:

在SE的学习中我们已有过简单了解。

我们可以注意到,除了int类型的包装类为Integer,char类型的包装类为Character外,其余基本类型的包装类均将首字母大写即可。

1.2 装箱和拆箱

装箱(装包):把基本数据类型变为包装类类型的过程,叫做装箱。

拆箱(拆包):把包装类类型变为基本数据类型的过程,叫做拆箱。

装箱又分为 自动装箱和显示装箱。

拆箱又分为 自动拆箱和显示拆箱。

1.2.1 装箱

装箱(装包):把基本数据类型变为包装类类型的过程,叫做装箱。

装箱分为 自动装箱和显示装箱。

1.2.1.1 自动装箱&显示装箱
public static void main(String[] args) {Integer a = 10;//自动装箱int b = 10;Integer c = Integer.valueOf(b);//显示装箱}

我们可以将数据直接赋值给包装类类型来自动装箱,也可以通过包装类中的方法来显示装箱。

1.2.2 拆箱

拆箱(拆包):把包装类类型变为基本数据类型的过程,叫做拆箱。

拆箱分为 自动拆箱和显示拆箱。

1.2.2.1 自动拆箱&显示拆箱
public static void main(String[] args) {Integer a = 10;//自动装箱(先装好箱,再来拆箱)int a1 = a;//自动拆箱int a2 = a.intValue();//手动拆箱double a3 = a.doubleValue();//手动拆箱}

1.2.3 自动拆箱&自动装箱 底层原理

其实不管是自动装箱,还是自动拆箱,底层都是帮我们调用了valueOf或者intValue/doubleValue/..... 方法:

1.3 包装类面试题 --->缓存数组

我们先来看以下代码:

读到这里,大家可以先猜测一下结果。

结果是出人意料的:

为什么会出现以上的结果的?明明两组数据都是包装类啊,为什么一组结果是true,而另一组结果是false呢?

要解决问题,我们就需要找到问题的主要矛盾。

我们可以发现,这几行代码,仅仅只发生了装箱。那我们就去看装箱是怎么操作的,也就是valueOf的源码是怎么工作的:

我们发现,当我们传入的值满足一个范围的时候,返回了一个数组中的值,而不满足这个范围的时候,则新返回了一个对象,既然返回了一个新对象,新对象用 == 来进行比较,那结果必然是false!

那这个范围是多少呢?

我们可以看到,范围为[-128,127] 。

也就是说,当我们要装箱的数据在这个范围当中时,是直接从一个数组中拿的数据,而这个数组就是缓存数组

缓存数组中共有256个数字,数组下标的范围为[0,255] ,存储着如下的数据:

所以当传入的数据在[-128,127]这个范围时,是直接从这个缓存数组中拿到的数据。

2、泛型

2.1 什么是泛型

顾名思义,泛型就是适用于许多许多类型。

在我们之前的学习中,我们可以将一个数据当做参数传到一个方法中,而泛型,是将一个数据类型当做参数传入,我们需要什么类型,就传入什么类型。

2.2 泛型的语法

类名后的 <E> 代表占位符,表示当前类是一个泛型类。
new关键字后<>中的类型实参可以不写,Java会根据第一个传入的参数自动的来推导出这个类型。
<>中参数传入规范:

2.3 泛型的使用

我们将Integer作为参数传入,那我们用E来接收的参数的类型必须为整型,不能再传入其他类型,如:字符串、字符型......:

这里就会帮我们进行自动类型检查,如果不是对应的类型,就会报错。

我们接收数据时也不需要强制类型转换,会进行自动类型转换

注意!注意!注意!!!

实例化对象时,<>中传入的类型只能为类类型,不能为普通数据类型!!!

泛型代码:

class myArray<E> {public Object[] array = new Object[10];public void setValue(int pos,E val) {array[pos] = val;}public E getValue(int pos) {return (E)array[pos];}
}
public class Test {public static void main(String[] args) {myArray<Integer> Array = new myArray<>();Array.setValue(0,10);//自动类型检查Array.setValue(1,100);//自动类型检查//Array.setValue(2,"dings");自动类型检查 发现错误Integer ret1 = Array.getValue(0);//自动类型转换System.out.println(ret1);}
}

2.4 裸类型(Raw Type) (了解)

裸类型是一个泛型类但没有传入类型实参,例如 Array  就是一个裸类型
我们发现,我们明明定义的是一个泛型类,但是我们实例化对象时并没有传入类型参数,却也没有发生报错,这是为什么呢?
答: 泛型是在JDK5引入的裸类型是为了兼容老版本的 API 保留的机制,所以不会报错。

2.5 泛型是如何进行编译的?

2.5.1 擦除机制

泛型是编译时期的一种机制,在运行的时候没有泛型的概念,也就是说,JVM当中没有泛型的概念。

在编译完成后,我们定义的<>中的T、E......等等,都会被擦除并且替换为Object,编译器生成的字节码在运行期间并不包含泛型的类型信息,这就是擦除机制

关于擦除机制的介绍:擦除机制

2.5 泛型的上界

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

2.5.1 语法

2.5.2 示例一

语法:

我们对泛型类定义了上界为Number ,那传入的类型只能是Number或者是Number的子类。

代码示例:

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

2.5.3 复杂示例二

例如:

那传入的类类型只能是实现了Comparable接口的类。

为什么要这样规定呢?

因为,我们使用的是泛型类,一旦我们要在类中进行数据的比较,那我们比较方法是未被定义的,就是说我们在写下这段代码时,还不知道传入的E会是什么类型,在方法中不能直接使用 >或者<来直接进行比较。于是,我们规定传入的类必须实现了Comparable接口,那就可以直接调用CompareTo方法来进行数据的比较了。

代码示例:

class A<E extends Comparable<E>> {//要求传入的类必须实现了Comparable接口,下面用来数据之间的比较public E findMax(E[] array) {//利用compareTo进行比较,找到数组中的最大值int max = 0;for (int i = 0; i < array.length; i++) {if (array[max].compareTo(array[i]) < 0) {max = i;}}return array[max];}
}
public class Student implements Comparable<Student>{//实现了Comparable接口public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Override//重写compareTo方法,规范比较行为public int compareTo(Student o) {return this.age - o.age;}public static void main(String[] args) {Student[] students = new Student[]{new Student("dinsg",10),new Student("fdd",100),new Student("kasg",21),new Student("hau",1)};A<Student> aaa = new A<>();Student maxStudent = aaa.findMax(students);System.out.println(maxStudent);}
}

2.6 泛型方法

未完待续....

相关文章:

数据结构预备知识(Java):包装类泛型

1、包装类 1.1 包装类 在Java中&#xff0c;每一个基本数据类型都有一个对应的包装类&#xff1a; 在SE的学习中我们已有过简单了解。 我们可以注意到&#xff0c;除了int类型的包装类为Integer&#xff0c;char类型的包装类为Character外&#xff0c;其余基本类型的包装类均…...

掌握Linux Vim:从基础到高级的全面指南

Vim是一款在Linux世界中备受推崇的文本编辑器,它以其强大的功能和高效的操作模式闻名于世。尽管Vim的学习曲线较陡,但一旦掌握,你将发现它在代码编辑和文本处理方面的无与伦比的优势。本文将从Vim的基础知识开始,逐步深入到高级用法和技巧,帮助你全面掌握这款强大的编辑器…...

打好“组合拳”,实现国有企业降本增效

在当前经济不确定性加剧、市场寒意明显的背景下&#xff0c;众多国有企业因历史积累的管理问题而陷入困境。随着经济形势的严峻&#xff0c;各行业普遍出现发展乏力的现象&#xff0c;促使企业开始重视“修炼内功”、“向内挖潜”&#xff0c;试图控制成本&#xff0c;以确保平…...

四川古力未来科技有限公司抖音小店解锁电商新机遇

在数字化浪潮席卷全球的今天&#xff0c;电商行业正以前所未有的速度蓬勃发展。四川古力未来科技有限公司紧跟时代步伐&#xff0c;积极拥抱变革&#xff0c;在抖音平台上开设小店&#xff0c;为品牌发展注入了新的活力。那么&#xff0c;四川古力未来科技有限公司抖音小店究竟…...

Maven之介绍

目录 一、简介 &#xff08;2&#xff09;为什么学习Maven&#xff1f; 二、小结 一、简介 &#xff08;1&#xff09;Maven 是一个 Java 项目管理和构建工具。它可以定义项目结构、项目依赖&#xff0c;并使用统一的方式进行自动化构建&#xff0c;是Java项目不可缺少的工具…...

简单了解java中的File类

1、File类 1.1、概述 File对象就表示一个路径&#xff0c;可以是文件路径也可以是文件夹路径&#xff0c;这个路径可以 是存在的&#xff0c;也可以是不存在的。 1.2、常见的构造方法 方法名称说明public File&#xff08;String pathname&#xff09;根据文件路径创建文件…...

边缘检测(一)-灰度图像边缘检测方法

灰度图像边缘检测是数字图像处理与机器视觉中经常遇到的一个问题&#xff0c;边缘检测是否连续、光滑是判断检测方法优劣的一个重要标准&#xff0c;下面通过一个实例提供灰度图像边缘检测方法&#xff0c;该方法对其他图像检测也具有一定的参考价值。 首先&#xff0c;读入一幅…...

2025计算机毕业设计选题题目推荐-毕设题目汇总大全

选题在于精&#xff0c;以下是推荐的容易答辩的选题&#xff1a; SpringBoot Vue选题: 基于SpringBoot Vue家政服务系统 基于SpringBoot Vue非物质文化遗产数字化传承 基于SpringBoot Vue兽医站管理系统 基于SpringBoot Vue毕业设计选题管理系统 基于SpringBoot Vue灾害应急救援…...

简易版 | 代码生成器(包含插件)

一、代码生成器 先导入依赖 <!-- Mybatis-Plus --> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.6</version> </dependency><!-- 代码生成器 --…...

【Python】Redis数据库

Redis数据库 Unit01一、Redis1.1 概述1.2 安装1.3 Redis-cli1.4 数据类型1.5 字符处理1.6 键的命名规则 二、通用命令三、字符串(String)3.1 概述3.2 常用命令3.3 应用场景 四、列表(List)4.1 概述4.2 常用命令 五、集合(SET)5.1 概述5.3 常用命令 六、有序集合6.1 概述6.2 常用…...

理解并应用:JavaScript响应式编程与事件驱动编程的差异

背景介绍 在现代JavaScript开发中&#xff0c;响应式编程&#xff08;Reactive Programming&#xff09;和事件驱动编程&#xff08;Event-Driven Programming&#xff09;是两种非常重要且常用的编程范式。虽然它们都用于处理异步操作&#xff0c;但在理念和实现方式上存在显…...

第4天:用户认证系统实现

第4天&#xff1a;用户认证系统实现 目标 实现用户认证系统&#xff0c;包括用户注册、登录、登出和密码管理。 任务概览 使用Django内置的用户认证系统。创建用户注册和登录表单。实现用户登出和密码重置功能。 详细步骤 1. 使用Django内置的用户认证系统 Django提供了…...

PostgreSQL源码分析 —— FunctionScan

本文分析一下FunctionScan的源码&#xff0c;加深一下理解。以SELECT * FROM generate_series(2,4);为例进行分析。 postgrespostgres# SELECT * FROM generate_series(2,4);generate_series -----------------234 (3 rows)postgrespostgres# explain SELECT * FROM generate…...

数据结构-十大排序算法集合(四万字精讲集合)

前言 1&#xff0c;数据结构排序篇章是一个大的工程&#xff0c;这里是一个总结篇章&#xff0c;配备动图和过程详解&#xff0c;从难到易逐步解析。 2&#xff0c;这里我们详细分析几个具备教学意义和实际使用意义的排序&#xff1a; 冒泡排序&#xff0c;选择排序&#xff0c…...

SpringBoot三层架构

目录 一、传统方式 二、三层架构 三、代码拆分 1、dao层 2、service层 3、control层 四、运行结果 一、传统方式 上述代码存在一定的弊端&#xff0c;在进行软件设计和软件开发中提倡单一责任原则&#xff0c;使代码的可读性更强&#xff0c;复杂性更低&#xff0c;可扩展性…...

uniapp微信小程序局部刷新,无感刷新,修改哪条数据刷新哪条

uniapp做微信小程序时&#xff0c;一个商品列表滑到几百条数据时&#xff0c;点进去详情跳转去编辑信息上下架等&#xff0c;修改完成回来商品列表就到第一条数据了&#xff0c;这样页面效果体验感不是很好&#xff0c;是因为我们把数据接口放在onshow中了&#xff0c;每次回来…...

golan的雪花id

今天记录一下 golang的雪花id golang的雪花id 还是比较简单的&#xff0c;其包含的含义以及组成我这就不讲了&#xff0c;好多大佬都有文章写过&#xff0c;我直接上怎么用 先 引入包 go get "github.com/bwmarrin/snowflake" 代码块 func main() {// 设置一个时…...

RK3568 CAN波特率500K接收数据导致CPU4满载

最近调试RK3568 CAN时发现&#xff0c;当CAN作为接收端&#xff0c;在快速接收数据时会导致cpu4满载。down掉can口或者断开外设时恢复正常。并且问题只是在部门CPU版本上出现。在CAN接收中断中打印log&#xff0c;能发现log是按照接收数据的时间打印的。 驱动(rockchip_canfd…...

AI实战 | 使用元器打造浪漫仪式小管家

浪漫仪式小管家 以前我们曾经打造过学习助手和待办助手,但这一次,我们决定创造一个与众不同的智能体,而浪漫将成为我们的主题。我们选择浪漫作为主题,是因为我们感到在之前的打造过程中缺乏了一些仪式感,无法给对方带来真正的惊喜。因此,这一次我们计划慢慢调试,将它发…...

什么是隐马尔可夫模型?

文章目录 一、说明二、玩具HMM&#xff1a;5′拼接位点识别三、那么&#xff0c;隐藏了什么&#xff1f;四、查找最佳状态路径五、超越最佳得分对齐六、制作更逼真的模型七、收获 关键词&#xff1a;hidden markov model 一、说明 被称为隐马尔可夫模型的统计模型是计算生物学…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

JVM 内存结构 详解

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

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...