【数据结构-JAVA】包装类 泛型

news2024/11/27 14:34:24

目录

1. 包装类

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

    1.2 装箱和拆箱

    1.3 一道面试题 

2. 泛型

    2.1 什么是泛型

3. 泛型是如何编译的

    3.1 擦除机制

4. 泛型的上界

5. 泛型方法


1. 包装类

在 Java 中,由于基本类型不是继承自 Object,为了在泛型代码中可以支持基本类型,Java 给每个基本类型都对应了 一个包装类型。如此一来,基本数据类型也能面向对象编程了。

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

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

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

1.2 装箱和拆箱

装箱,也叫装包,把基本数据类型变为对应的包装类。

    public static void main(String[] args) {
        int a = 10;
        //Integer val = a; //自动装箱
        //Integer val = (Integer)a;//自动装箱 
        Integer val = Integer.valueOf(a); //显示装箱
        //Integer val = new Integer(a); //显示装箱
        System.out.println(val);
    }

拆箱,也叫拆包,把包装类转变成基本数据类型。

    public static void main(String[] args) {
        Integer val = 100;
        int i = val; //自动拆箱
        //int i = (int)val; //自动拆箱
        System.out.println(i);
        int j = val.intValue(); //显示拆箱,拆成 int 类型
        System.out.println(j);
        double k = val.doubleValue(); //显示拆箱,拆成 double 类型
        System.out.println(k);
        float l = val.floatValue(); //显示拆箱,拆成 float 类型
        System.out.println(l);
    }

1.3 一道面试题 

下面代码输出什么?

    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);
        Integer c = 200;
        Integer d = 200;
        System.out.println(c == d);
    }

 输出 

        true
        false

IntegerCache 是 Integer 中的内部类,low 的值为 -128,而 high 的值为 127,cache 是一个数组:

在 valueOf 这个方法中,如果i ∈[-128,127],则返回 cache 数组里的元素:

但如果 i 超出范围,那么就会返回 new 一个对象。根据前面所学我们知道,== 比较的是地址,所以比较的结果才会使 false。

2. 泛型

2.1 什么是泛型

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

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

在介绍泛型之前,能不能实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值?

思路:

1. 我们以前学过的数组,只能存放指定类型的元素,例如:int[] array = new int[10];  String[] strs = new String[10];

2. 所有类的父类,默认为 Object 类。数组是否可以创建为 Object ?

class MyArray{
    public Object[] obj = new Object[3];
    public Object getPos(int pos){
        return obj[pos];
    }
    public void setObj(int pos,Object val){
        obj[pos] = val;
    }
}


public class Text {
    public static void main(String[] args) {
        MyArray myArray = new MyArray();
        myArray.setObj(0,100);
        myArray.setObj(1,"hello");
        myArray.setObj(2,10.5);
        int a = (int)myArray.getPos(0); //拆箱
        String b = (String)myArray.getPos(1); //拆箱
        double c = (double)myArray.getPos(2); //拆箱
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}

上述数组的确可以存储任何类型的数据,但读取时,却需要强转。更多情况下,我们还是希望他只能够持有一种数据类型。而不是同时持有这么多类型。所以,泛型的主要目的:就是指定当前的容器持有特定类型的对象。此时,需要把类型,作为参数传递。需要什么类型,就传入什么类型:

class MyArray<T>{ 
    public T[] obj = (T[])new Object[3]; //*
    public T getPos(int pos){
        return obj[pos];
    }
    public void setObj(int pos,T val){
        obj[pos] = val;
    }
}
public class Text {
    public static void main(String[] args) {
        //实例化对象的同时,指定当前泛型类的指定参数类型是 Integer
        MyArray<Integer> myArray = new MyArray<Integer>(); //**
        //就可以存储指定的数据类型
        myArray.setObj(0,100); //#
        myArray.setObj(1,121);
        myArray.setObj(2,141);
        int a = myArray.getPos(0); //***
        System.out.println(a);
        System.out.println("==========================");
        //实例化对象的同时,指定当前泛型类的指定参数类型是 String ,第二个< >的内容可以省略
        MyArray<String> myArray1 = new MyArray<>();
        myArray1.setObj(0,"haha");
        myArray1.setObj(1,"heihei");
        myArray1.setObj(2,"hehe");
        String b = myArray1.getPos(1);
        System.out.println(b);
    }

代码解释:

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

了解:

【规范】类型形参一般使用一个大写字母表示,常用的名称有:

E 表示 Element

K 表示 Key

V 表示 Value

N 表示 Number

T 表示 Type

S, U, V 等等 - 第二、第三、第四个类型

2. 注释 * 处,不能 new 泛型类型的数组,即泛型类当中,不能实例化一个泛型类数组:

T[] ts = new T[3];//是不对的

3. 泛型是把类型作为参数传递,泛型只能接受类,所有的基本数据类型必须使用包装类!注释 ** 处,< >里指定的参数类型必须是引用类型,而不能是基本数据类型

4. 注释 *** 处,不需要进行强制类型转换,编译器会自动帮我们数据转换

5. 注释 # 处,编译器会在存放元素的时候帮助我们进行类型检查

第四、第五点是泛型在编译时完成的。

3. 泛型是如何编译的

3.1 擦除机制

那么,泛型到底是怎么编译的?

IDEA  点击 View -> Show ByteCode :

可以看到,在编译完成之后,编译器将所有的 T 替换为 Object ,这种机制,我们称为:擦除机制。 Java 的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

官方中,对于泛型类的数组声明是不写成这样的:public T[] obj = (T[])new Object[3];

官方的正确写法:

class MyArray<T>{
    //public T[] obj = (T[])new Object[3];
    public Object[] obj = new Object[3]; //在 Java 官方中,泛型类中的数组声明
    public T getPos(int pos){
        return (T)obj[pos];
    }
    public void setObj(int pos,T val){
        obj[pos] = val;
    }
}

4. 泛型的上界

由于泛型的擦除机制会将传入的类型变量擦除成 Object 类,但有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

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

......

}

类型边界有两种,一是接口,意味着指定的参数类型一定实现了该接口,二是某一具体类,意味着形参是该类的子类,或是该类本身。

示例1:

类型边界为接口:找到数组中的最大值

class Alg<E extends Comparable>{
    public E findMax(E[] arrays){
        E max = arrays[0];
        for (int i = 1; i < arrays.length; i++) {
            if(max.compareTo(arrays[i]) < 0){
                max = arrays[i];
            }
        }
        return max;
    }
}

public class Text {
    public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] arr = {1,2,5,7,24,62,555,36,77,42,31,59,92};
        Integer max = alg.findMax(arr);
        System.out.println(max);
    }
}

示例2:

类型边界为 Number 类:

通过查询帮助手册可知,Number 有以下我们所熟悉的包装类:

5. 泛型方法

基本语法:

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

......

}

class Alg1 {
    public<E extends Comparable<E>> E findMax1(E[] arrays){
        E max = arrays[0];
        for (int i = 1; i < arrays.length; i++) {
            if(max.compareTo(arrays[i]) < 0){
                max = arrays[i];
            }
        }
        return max;
    }
}
public class Text {
    public static void main(String[] args) {
        Alg1 alg1 = new Alg1();
        Integer[] arr = {1,2,5,7,24,62,555,36,77,42,31,59,92};
        Integer max = alg1.<Integer>findMax1(arr);
        //也可以省略:Integer max = alg1.findMax1(arr);
        System.out.println(max);
    }
}

也可以使用泛型的静态方法:

class Alg2 {
    public static <E extends Comparable<E>> E findMax1(E[] arrays){
        E max = arrays[0];
        for (int i = 1; i < arrays.length; i++) {
            if(max.compareTo(arrays[i]) < 0){
                max = arrays[i];
            }
        }
        return max;
    }
}
public class Text {
    public static void main(String[] args) {
        Integer[] arr = {1,2,5,7,24,62,555,36,77,42,31,59,92};
        Integer max = Alg2.findMax1(arr);
        System.out.println(max);
    }
}

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

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

相关文章

为什么 FIQ 比 IRQ 的响应速度更快?

目录 1、FIQ在异常向量表位于最末 2、FIQ模式有5个私有寄存器 3、FIQ的优先级高于IRQ 1、FIQ在异常向量表位于最末 一般来说&#xff0c;处理器跳转到异常向量表以后&#xff0c;会根据当前的异常源类型&#xff0c;执行下一次的跳转指令&#xff0c;但是FIQ在异常向量表的…

尚医通:项目搭建-提交到Git(六)

&#xff08;1&#xff09;前后端概念介绍 &#xff08;2&#xff09;搭建项目后端环境 &#xff08;3&#xff09;提交到Git仓库 &#xff08;1&#xff09;前后端概念介绍 &#xff08;2&#xff09;搭建项目后端环境 项目模块构建 hospital-manage&#xff1a;医院接口模拟…

微服务框架 SpringCloud微服务架构 分布式缓存 44 Redis 分片集群 44.5 RedisTemplate访问分片集群

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 分布式缓存 文章目录微服务框架分布式缓存44 Redis 分片集群44.5 RedisTemplate访问分片集群44.5.1 RedisTemplate访问分片集群44 Redis 分片…

手把手教你使用SpringBoot做一个员工管理系统【代码篇·上】

手把手教你使用SpringBoot做一个员工管理系统【代码篇上】1.登录功能2.登录拦截器的实现3.展示员工列表1.登录功能 首先把登录页面的表单提交地址写一个controller <form class"form-signin" th:action"{/user/login}">表单的name属性不可少&#…

13、腾讯云轻量应用服务器挂载文件系统

前言&#xff1a;腾讯云轻量应用服务器腾讯云文件存储&#xff08;Cloud File Storage&#xff0c;CFS&#xff09;系统的使用小记 轻量应用服务器系统版本是windows server 2012r 一、必要概念 1.1 轻量应用服务器 轻量应用服务器&#xff08;TencentCloud Lighthouse&#x…

【MySQL】浅谈事务与隔离级别

文章目录1. 事务概述2. 事务的特性3. 事务的隔离级别1. 事务概述 什么是事务&#xff1f; 在MySQL中的事务&#xff08;Transaction&#xff09;是由存储引擎实现的&#xff0c;在MySQL中&#xff0c;只有InnoDB存储引擎才支持事务。事务处理可以用来维护数据库的完整性&#x…

大数据学习--使用Java API访问HDFS

Java API访问HDFS编写Java程序访问HDFS1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、启动集群HDFS服务5、在HDFS上创建文件编写Java程序访问HDFS 1、创建Maven项目 创建Maven项目 - HDFSDemo 单击【Create】按钮 2、添加相关依赖 在pom.xml文件里添加hadoop和…

react的jsx和React.createElement是什么关系?面试常问

1、JSX 在React17之前&#xff0c;我们写React代码的时候都会去引入React&#xff0c;并且自己的代码中没有用到&#xff0c;这是为什么呢&#xff1f; 这是因为我们的 JSX 代码会被 Babel 编译为 React.createElement&#xff0c;我们来看一下babel的表示形式。 需要注意的是…

Kotlin 原生拓展函数与非拓展函数

先看一下图文 根据定义的性质可分为两类 非拓展函数 repeat 循环函数,可使用该函数执行一些有限循环任务,务必在构造函数传入循环次数 repeat(repeatNumber:Int 1) with 条件补充区域,可在某些需要两个或者多个函数对象直接的属性进行依赖操作时使用 …

Python 读取图像方式总结

读取并显示图像 opencv3库scikit-image库PIL库读取图像结果分析 打印图像信息 skimage获取图像信息PIL获取图像信息 读取并显示图像方法总结 PIL库读取图像Opencv3读取图像scikit-image库读取图像参考资料 学习数字图像处理&#xff0c;第一步就是读取图像。这里我总结下如何…

深度学习——CPU,GPU,TPU等硬件说明(笔记)

目录 深度学习硬件&#xff1a;CPU和GPU 深度学习硬件&#xff1a;TPU 深度学习硬件&#xff1a;CPU和GPU 1.提升CPU的利用率Ⅰ&#xff1a;提升空间和时间的内存本地性 ①在计算ab之前&#xff0c;需要准备数据 主内存->L3->L2->L1->寄存器 L1&#xff1a;访…

【LeetCode每日一题:1697. 检查边长度限制的路径是否存在~~~并查集+数组排序+排序记录下标位置】

题目描述 给你一个 n 个点组成的无向图边集 edgeList &#xff0c;其中 edgeList[i] [ui, vi, disi] 表示点 ui 和点 vi 之间有一条长度为 disi 的边。请注意&#xff0c;两个点之间可能有 超过一条边 。 给你一个查询数组queries &#xff0c;其中 queries[j] [pj, qj, li…

抖音商家引流的正确方法,抖音商家引流脚本实操教程。

大家好我是你们的小编一辞脚本&#xff0c;今天给大家分享新的知识&#xff0c;很开心可以在CSDN平台分享知识给大家,很多伙伴看不到代码我先录制一下视频 在给大家做代码&#xff0c;给大家分享一下抖音商家引流脚本的知识和视频演示 不懂的小伙伴可以认真看一下&#xff0c…

【lssvm回归预测】基于遗传算法优化最小二乘支持向量机GA-lssvm实现数据回归预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

图书商城小程序开发,实现图书便捷式选购

1995年联合国教文组织将4月23日规定为世界读书日&#xff0c;由此可见对全世界人民来说读书都是一件很重要的事。并且据调查数据显示&#xff0c;去年我国成年国民图书阅读量达到了59.7%&#xff0c;同比增长了0.2个百分点&#xff1b;人均纸质图书阅读量为4.76&#xff0c;较上…

记一次线上问题 → 对 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 的片面认知

问题背景 需求背景 需求&#xff1a;对商品的上架与下架进行管控&#xff0c;下架的商品不能进行销售 上架与下架的管控&#xff0c;在我负责的项目&#xff08;单据系统&#xff09;中实现&#xff1b;销售的控制则是在另外一个项目&#xff08;POS系统&#xff09;中实现的…

人工智能课后作业_python实现广度优先遍历搜索(BFS)(附源码)

2 广度优先遍历搜索(BFS) 2.1算法介绍2.2实验代码2.3实验结果2.4实验总结 2.1算法介绍 广度优先搜索算法&#xff08;英语&#xff1a;Breadth-First-Search&#xff0c;缩写为BFS&#xff09;&#xff0c;是一种图形搜索算法。简单的说&#xff0c;BFS是从根节点开始&#…

MATLAB动态导入文件功能(txt文件读入)

目录 一、界面搭建 1.axes坐标轴 2.LIST表 3.button按钮 二、属性 三、代码实现 一、界面搭建 1.axes坐标轴 需要有一个可以显示点的axes&#xff0c;以及一个展示点坐标XYZ的LIST表控件 2.LIST表 LIST需要添加表头&#xff0c;XYZ&#xff0c;行1,2,3,4,.. 右键列表…

降本增效: 蚂蚁在 Sidecarless 的探索和实践

文&#xff5c;王发康 &#xff08;花名&#xff1a;毅松 &#xff09; 蚂蚁集团技术专家、MOSN 项目核心开发者 深耕于高性能网络服务器研发&#xff0c;目前专注于云原生 ServiceMesh、Nginx、MOSN、Envoy、Istio 等相关领域。 本文 5574 字 阅读 14 分钟 前言 从单体到分…

三、数据链路层(二)封装成帧和透明传输

目录 2.1字符计数法 2.2字符填充的首尾定界符法 2.3零比特填充的首尾标志法 2.4违规编码法 组帧就是一段数据的前后分别添加首部和尾部&#xff0c;确定帧的界限。 组帧的目的是解决帧定界、帧同步&#xff08;接收方应能从接收到的二进制比特流中区分出帧的起始和终止&am…