数据结构初阶(算法的复杂度 + 包装类 + 泛型)

news2025/1/6 18:28:39

文章目录

  • 一、算法复杂度
    • 1. 算法效率
    • 2. 时间复杂度
      • (1) O的渐进表示法
    • 3. 空间复杂度
  • 二、包装
    • 2.1 为什么会出现包装
    • 2.2 分类
    • 2.3 装箱和拆箱
      • (1)装箱/装包
      • (2)拆箱/拆箱
  • 三、泛型
    • 3.1 泛型的基本概念
    • 3.2 泛型的使用
    • 3.3 泛型的编译
    • 3.4 泛型的上界

一、算法复杂度

1. 算法效率

  • 我们一般是通过算法的复杂度去判断一个算法的好坏,其评判的标准,一般是从时间、空间两个维度来衡量,即时间复杂度和空间复杂度
  • 时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间
  • 早期,我们更看重于空间复杂度,但随着技术的发展,我们现在更看重时间复杂度

2. 时间复杂度

  • 概念
    • 算法的时间是难以高效率地测出来的,所以我们通过一个函数去定量描述算法的时间复杂度
      • 不能掐表,因为运行的时间和电脑的硬件是有关系的
      • 时间是要运行的时候才能体现出来,不能每次都上机测试,所以时间复杂度是一个分析方式
      • 时间复杂度是一个估算的值
  • 计算:先算出执行的次数,将其转化为函数之后,用O的渐进表示法表示

(1) O的渐进表示法

  • 大O符号(Big O notation):是用于描述函数渐进行为的数学符号

  • 推导大O阶方法

    • 用常数1取代运行时间中的所有加法常数。
    • 在修改后的运行次数函数中,只保留最高阶项。
    • 如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶
  • 效果:去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数

  • 结果形式

    • 最坏情况:任意输入规模的最大运行次数(上界)
    • 平均情况:任意输入规模的期望运行次数
    • 最好情况:任意输入规模的最小运行次数(下界)
      在实际中一般情况关注的是算法的最坏运行情况

3. 空间复杂度

概念:对一个算法在运行过程中临时占用存储空间大小的量度,在实际上算的是变量的个数
计算方式:求出变量的个数后,用大O渐进表示法表示

二、包装

2.1 为什么会出现包装

    在Java中,由于基本数据类型不是继承与Object的,为了在泛型代码中可以支持基本类型,Java中每一个基本数据类型都有一个对应的包装类
    对于基本类型来说,包装类中的属性和方法,可以让数据的转换等使用方法更加方便

2.2 分类

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

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

2.3 装箱和拆箱

(1)装箱/装包

  • 概念:基本类型------------>包装类型
  • 实现方式:新建一个 包装类型对象,将基本数据类型的值放入对象的某个属性中
  • 代码示例:
public static void main1(String[] args) {
    int a = 10;
    int b = 20;
    //自动装箱
    Integer i = a;//与Integer i = Integer.valueOf(a);是一样的,JVM会帮着调用一个valueOf方法
    Integer iiii = (Integer) b;

    显示装箱
    int c = 30;
    int d = 40;
    Integer iii = Integer.valueOf(c);//使用类调用的,说明是被static修饰的

    Integer ii = new Integer(d);
}

❤️Integer.valueOf方法介绍

  • 源代码
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
  • 含义
    • 如果该 int 类型的值在-127 ~ 128 之间,会缓存在一个数组中,每个数对应的下标是 i + (-IntegerCache.low)
    • 如果不是在-127 ~ 128 之间,会new一个新的对象

(2)拆箱/拆箱

  • 概念:包装类型------------>类型类型
  • 实现方式:将包装类型对象的值取出,放到一个基本数据类型中
  • 代码示例
    public static void main2(String[] args) {
        Integer a = 10;
        //自动拆箱
        int ii = a;
        int iii = (int)a;

        //显示拆箱
        int i = a.intValue();   //用对象调用,说明这是一个类中的方法
        float f = a.floatValue();
    }

三、泛型

3.1 泛型的基本概念

  • 什么是泛型
    泛型就是适用于许多类型,从代码上讲,就是将类型作为参数
  • 泛型的目的
    虽然我们希望泛型适用于许多类型(什么类型的都可以接收),但是如果同时存有不同类型,数据的拿取就会变得很麻烦。
    所以更多情况下,我们还是希望泛型只能持有一种数据类型。
    泛型的主要目的,就是指定当前的容器,要持有什么类型的对象,在编译的时候,让编译器去做检查类型和类型的转换
  • 注意
    Java的泛型机制是在编译级别实现的,编译器生成的字节码在运行期间并不包含泛型的类型信息

3.2 泛型的使用

<>里面一定是个引用类型

语法(1)------------>定义一个泛型类
class 泛型类名称<类型形参列表>{
       //这里可以使用类型参数
}

语法(2)------------>定义一个继承某个类的泛型类
class 泛型类名称<类型形参列表> extends 继承类(这里可以使用类型参数){
       //可以只使用部分类型参数
}

语法(3)------------>定义一个泛型类引用
泛型类<类型实参>变量名;      

语法(4)------------>实例化一个泛型类对象
new 泛型类<类型实参>(构造方法实参);      

语法(5)------------>裸类型
概念:是一个泛型类但是没有带着类型实参,意味着什么都能放,那取出来还要强转
注意:不要主动去使用裸类型,因为这是为了兼容老版本保留的机制

  • 写法注意
class MyArray4<T>{  //定义一个泛型类,T这边的效果就是传什么就是什么,T表示的是这是一个占位符,表示当前类是一个泛型类
    public Object[] objects = new Object[10];   //最好的写法
    //public T[] objects2 = new T[5];   错误,数组在new的时候,后面一定要跟一个具体的类型
    public T[] objects3 = (T[])new Object[5];   //这种可以,但是不好

    public Object getPos(int pos){
        return objects3[pos];
    }
}

public class Test {
    public static void main(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();   //语法3+语法4,Integer表示指定传的是int类型的
        MyArray<Integer> myArray1 = new MyArray<Integer>();   //裸类型
        //效果和上一行是一样的,实例化对象那边的<>中的包装类型是可以省略的,因为可以根据上下文推导出实例化所需要的类型实参

        //数组在new的时候,后面一定要跟一个具体的类型,因为T这种占位符在运行的时候是不知道是什么的
        //T[] ts = new T[5];
    }
}

  • 规范写法(还是用Object接收,取的时候,强制转换就好了)
class MyArray1<T>{
    public Object[] objects = new Object[10];

    public T getPos(int pos){
        return (T)objects[pos];
    }

    public void setPos(int pos, T val){
        objects[pos] = val;
    }
}

public class Test{
    public static void main(String[] args){
        MyArray1<Integer> myArray1 = new MyArray1<>();
        myArray1.setPos(0, 20);
        System.out.println(myArray1.getPos(0));

        MyArray1<String> myArray2 = new MyArray1<>();
        myArray2.setPos(0, "aaa");
        System.out.println(myArray2.getPos(0));
    }
}

在这里插入图片描述

3.3 泛型的编译

泛型的编译中需要遵循一个擦除机制
擦除机制就是在编译的过程当中把所有的T替换成Object这种机制,所以在运行的时候是没有T的,即没有泛型的概念

  • 既然T[5] = new T[5]在编译的时候,会把T替换成Object,不是相当于Object[5] = new Object[5]吗?为什么是错的?
    • :因为数组在new的时候后面一定需要的是一个具体的类型
  • 类型擦除,一定是把T变成Object吗?

❤️为什么不能实例化泛型数组
错误示例

class MyArray<T>{
	public T[]array = (T[])new Object[10];

	public T getPos(int pos){
		return this.array[pos];
	}
	
	public void setVal(int pos, T val){
		this.arrar[pos] = val;
	}
	
	public T[] getArray(){
		return array;
	}
}

public class Main{
	public static void main(String[]args){
		MyArrar<Integer> myArray1 = new MyArray<Integer>();
		Integer[] intgers = myArray1.getArray();   //不知道该用什么接收
	}
}

会报错,返回的Object数组里面,可能存放的是任何的数据类型,运行的时间直接传给Integer等类型的数组,会被编译器认为不安全
那怕是强转都不行,因为Object类型表示这里面什么类型都可以放,即可能有char、String等类型,全部都转为Integer会不安全

正确解法

class MyArray1<T>{
    public Object[] objects = new Object[10];

    public T getPos(int pos){
        return (T)objects[pos];
    }

    public void setPos(int pos, T val){
        objects[pos] = val;
    }

    public Object[] getArray(){
        return objects;
    }
}

public class Test{
    public static void main(String[] args){
        MyArray1<Integer> myArray1 = new MyArray1<>();
        myArray1.setPos(0, 20);
        System.out.println(myArray1.getPos(0));

        MyArray1<String> myArray2 = new MyArray1<>();
        myArray2.setPos(0, "aaa");
        System.out.println(myArray2.getPos(0));
    }
}

3.4 泛型的上界

概念:在定义泛型类时,对传入的类型变量通过类型边界作一定的约束
语法
         class 泛型类名称<类型形参 extends 类型边界>{
         }
示例
         class MyArray< E extends Number>{
         }
         E要么是Number的子类,要么就是Number

代码示例 ------------------> 写一个泛型类,求数组中的最大值

<>里面的一定是个引用类型,而引用类型是不可以通过大于和小于进行比较的,因为T在编译的时候会变成Object类,Object类是所有类的父类,本身并没有关联Comparable接口,所以这个泛型类要关联Comparable接口

class Alg<T extends Comparable<T>>{   //擦除为一个实现了这个接口的类型
    public T findMax(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            //引用类型不可以通过 大于和小于进行比较
            if(max.compareTo(array[i]) < 0 ) {
                max = array[i];
            }
        }
        return max;
    }
}

public class Test{
    public static void main(String[] args){
        Alg<Integer> alg = new Alg<>();
        Integer[] array = {1, 5, 2, 7, 19, 4};
        Integer max = alg.<Integer>findMax(array);  //可以通过array类判断传的是什么类型的数据
        System.out.println(max);
    }
}
//这是用静态泛型方法去写
class Alg2 {
    public static<T extends Comparable<T>> T findMax(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(max.compareTo(array[i]) < 0 ) {
                max = array[i];
            }
        }
        return max;
    }
}
public class Test2 {

    public static void main(String[] args) {
        Integer[] array = {1,5,2,7,19,4};
        Integer max = Alg2.<Integer>findMax(array);//可以通过array类判断传的是什么类型的数据
        System.out.println(max);
    }
}

在这里插入图片描述

泛型方法

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

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

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

相关文章

2023 年 3 月 GameFi 月度报告

作者&#xff1a;danielfootprint.network 数据来源&#xff1a;Monthly GameFi Report 三月的 GameFi 世界相对沉寂&#xff0c;没有重大的消息公开&#xff0c;没有亮眼的游戏出现&#xff0c;也没有死亡螺旋的发生。 GameFi 领域的重要名字 Splinterlands 和 Hive 开始面…

Redis一主二从搭建

Redis一主二从环境搭建 一主二从 准备工作 安装VMWare 下载镜像 创建下面的目录 Redis-Cluster master mastervmdk slave00 slave00vmdk slave01 slave00vmdk VMWare中安装CentOS7 自定义(高级) 默认 安装程序光盘映像文件 命名虚拟机&#xff0c;选择我们刚才创建的…

ASEMI代理ADAU1961WBCPZ-R7原装ADI车规级ADAU1961WBCPZ-R7

编辑&#xff1a;ll ASEMI代理ADAU1961WBCPZ-R7原装ADI车规级ADAU1961WBCPZ-R7 型号&#xff1a;ADAU1961WBCPZ-R7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LFCSP-32 批号&#xff1a;2023 引脚数量&#xff1a;32 安装类型&#xff1a;表面贴装型 ADAU1961WBCPZ-…

通过简单demo让你秒懂Python的编译和执行全过程

基本说明 python 是一种解释型的编程语言&#xff0c;所以不像编译型语言那样需要显式的编译过程。然而&#xff0c;在 Python 代码执行之前&#xff0c;它需要被解释器转换成字节码&#xff0c;这个过程就是 Python 的编译过程。 DEMO演示讲解 假设我们有以下 Python 代码&…

常见安全设备

文章目录前言安全厂商安全设备种类拓扑图防火墙IDSIPSwaf上网行为管理器数据库审计系统全流量设备蜜罐态势感知前言 最近在了解安全设备的基本原理&#xff0c;简单做一下笔记。 安全厂商 深信服、浪潮、奇安信、绿盟、山石网科、启明星辰、安恒、360、新华3 安全设备种类 …

【CSS】元素显示与隐藏 ( display 隐藏对象 | visibility 隐藏对象 | overflow 隐藏对象 )

文章目录一、元素的显示与隐藏二、display 隐藏对象1、display 隐藏对象语法说明2、display 显示元素代码示例3、display 隐藏元素代码示例三、visibility 隐藏对象1、visibility 隐藏对象语法说明2、visibility 显示对象代码示例3、visibility 隐藏对象代码示例四、overflow 隐…

大数据项目实战之数据仓库:电商数据仓库系统——第5章 数据仓库设计

第5章 数据仓库设计 5.1 数据仓库分层规划 优秀可靠的数仓体系&#xff0c;需要良好的数据分层结构。合理的分层&#xff0c;能够使数据体系更加清晰&#xff0c;使复杂问题得以简化。以下是该项目的分层规划。 5.2 数据仓库构建流程 以下是构建数据仓库的完整流程。 5.2.1 …

在unreal中的基于波叠加的波浪水面材质原理和制作

关于水的渲染模型 如何渲染出真实的水体和模拟&#xff0c;是图形学&#xff0c;游戏开发乃至仿真领域很有意思的一件事 记得小时候玩《Command & Conquer: Red Alert 3》&#xff0c;被当时的水面效果深深震撼&#xff0c;作为一款2008年出的游戏&#xff0c;现在想起它…

RK3399平台开发系列讲解(基础篇)POSIX 定时器

🚀返回专栏总目录 文章目录 一、clockid二、sigevent三、timerid四、flags五、 value & old_value六、POSIX 定时器的优势沉淀、分享、成长,让自己和他人都能有所收获!😄 📢为了克服传统定时器的局限性,POSIX 标准组织设计了新的计时器接口和规范,使它们能提供更…

Java安全学习之RMI

最近在看Phith0n师傅的知识星球的Java安全漫谈系列&#xff0c;随手记下笔记 RMI全称远程方法调用(Remote Method Invocation)。这是允许驻留在一个系统(JVM)中的对象调用在另一个JVM上运行的对象的一种机制&#xff0c;能够远程调用远程对象的方法。 RMI通信过程、原理 我们首…

SSM实战-外卖项目-06-用户地址簿功能、菜品展示、购物车、下单(一个业务涉及5张表)

文章目录外卖项目-第六天课程内容1. 用户地址簿功能1.1 需求分析1.2 数据模型1.3 导入功能代码1.4 功能测试 &#xff08;其实需求分析里我就自己写了一份代码&#xff0c;而且测试过了&#xff0c;下面再测试了一遍&#xff09;2. 菜品展示2.1 需求分析2.2 前端页面分析2.3 代…

关于二叉树访问顺序的选择题

第一题&#xff1a; 从题目中我们可以得出这是棵完全二叉树&#xff08;最后一列不满&#xff0c;且连续&#xff09;&#xff0c;层次顺序。 我们可以推出树的形状&#xff1a; 我们现根据层次遍历的性质画出出栈的图&#xff1a; ABCDEFGH 最开始是A所以第一个位置为A&…

STC单片机波特率初值计算以及通用串口配置程序

STC单片机波特率初值计算以及通用串口配置程序&#x1f516;这里以STC15手册上的数据展开。&#x1f530;串口模式一&#xff1a;可变波特率8位数据方式。以为最为常用的配置模式。&#x1f33f;定时器1模式0:16位定时器计数器&#x1f33f;定时器1模式2:8位定时器计数器 ✨当然…

linux高级存储功能

高级存储功能 1、Stratis管理分层存储 通过Stratis&#xff0c;便捷的使用精简配置&#xff08;thin provisioning&#xff09;&#xff0c;快照&#xff08;snapshots&#xff09;和基于池&#xff08;pool-based&#xff09;的管理和监控的等高级存储功能。 &#xff08;1&a…

加拿大亚马逊FBA海运收费标准有哪些

众所周知&#xff0c;加拿大亚马逊的海运物流费用一般有头程运费、尾端派送费和仓储费等其他费用。那么&#xff0c;加拿大亚马逊FBA海运收费标准有哪些呢?接下来一起来了解下加拿大亚马逊FBA海运收费标准和费用。加拿大亚马逊FBA海运收费标准有哪些? 加拿大亚马逊FBA海运收费…

《Java8实战》第6章 用流收集数据

collect 是一个归约操作&#xff0c;就像 reduce 一样可以接受各种做法作为参数&#xff0c;将流中的元素累积成一个汇总结果。具体的做法是通过定义新的Collector 接口来定义的&#xff0c;因此区分 Collection、Collector 和 collect 是很重要的。用 collect 和收集器能够做什…

PADS-微处理器、USB转UART芯片、MINI-USB PCB封装设计

目录 1 微处理器PCB封装设计 2 USB转UART芯片PCB封装设计 3 MINI-USB PCB封装设计 4 添加验证 详细步骤不再文字说明&#xff0c;直接截取关键步骤截图 1 微处理器PCB封装设计 查看芯片手册 器件高度 器件高度1.6 管脚中心点间距0.5&#xff0c;管脚焊盘长1.2、宽0.3&…

[ 云计算 | Azure ] Chapter 04 | 核心体系结构之数据中心、区域与区域对、可用区和地理区域

本章节主要内容进行讲解&#xff1a;Azure云计算的核心体系结构组件中的&#xff1a;Azure物理基础设施&#xff08;Physical infrastructure&#xff09;&#xff0c;区域&#xff08;Regions&#xff09;和区域对&#xff08;Region Pairs&#xff09;、地理数据中心&#xf…

一文解决ethtool 原理介绍和解决网卡丢包排查思路

前言 之前记录过处理因为 LVS 网卡流量负载过高导致软中断发生丢包的问题&#xff0c;RPS 和 RFS 网卡多队列性能调优实践[1]&#xff0c;对一般人来说压力不大的情况下其实碰见的概率并不高。这次想分享的话题是比较常见服务器网卡丢包现象排查思路&#xff0c;如果你是想了解…

UE 简单插件制作

本文主要是提供几个写UE插件的实例&#xff0c;借此来了解在UE里使用C创建自定义插件的做法&#xff1a; 写一个使场景变暗的简单插件写一个自定义窗口&#xff0c;展示项目里所有的动画资产 写一个使场景变暗的简单插件 参考&#xff1a;Unreal Engine 5 - Writing Plugins …