【数据结构 |集合框架、泛型】初始集合框架、时间(空间)复杂度、简单认识泛型

发布于:2024-06-17 ⋅ 阅读:(13) ⋅ 点赞:(0)

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 
🎈🎈作者主页: 🎈丠丠64-CSDN博客🎈


✨✨ 帅哥美女们,我们共同加油!一起进步!✨✨ 

目录

集合框架

时间复杂度

大O渐进表示法:

空间复杂度

包装类

1.装箱和卸箱

泛型

1.泛型的定义

2.擦除机制

3.泛型的上届

4.泛型方法 


集合框架

Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces和其实现类 classes。

集合框架是由不同的很多类组成的一个集合,而不同类的背后有着不同的数据结构(数据 + 结构)储存、组织数据的方式不一样

  • Collection是一个接口,包含了大部分容器常用的一些方法
  • List是一个接口,规范了ArrayList LinkedList中要实现的方法
  • ArrayList实现了List接口,底层为动态类型顺序表
  • LinkedList:实现了List接口,底层为双向链表
  • Stack:底层是栈,栈是一种特殊的顺序表
  • Queue:底层是队列,队列是一种特殊的顺序表
  • Deque:是一个接口
  • Set:集合,是一个接口,里面放置的是K模型
  • HashSet:底层为哈希桶,查询的时间复杂度为O(1)
  • TreeSet:底层为红黑树,查询的时间复杂度为O( log2N),关于key有序的
  • Map:映射,里面存储的是K-V模型的键值对
  • HashMap:底层为哈希桶,查询时间复杂度为O(1)
  • TreeMap:底层为红黑树,查询的时间复杂度为O( log2N),关于key有序

时间复杂度

时间复杂度用来决定算法所需要的运行速度。

算法的时间复杂度是一个数学函数,算法中基本操作的执行次数,为算法的时间复杂度。 

大O渐进表示法:

我们不一定要计算精准的执行次数,而只需要大概算出大概执行次数

O 符号( Big O notation ):是用于描述函数渐进行为的数学符号
使用方法:
  • 用常数一取代运行时间里全部的加法常数
  • 在修改后运行次数函数中只保留最高项
  • 如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数,在实际中一般情况关注的是算法的最坏运行情况(N次找到)

所以该时间复杂度为


空间复杂度

空间复杂度用来决定算法所需要的额外空间,空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法


包装类

Java 中,由于基本类型不是继承自 Object ,为了在泛型代码中可以支持基本类型, Java 给每个基本类型都对应了一个包装类型。
基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

1.装箱和卸箱

装箱:装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中

拆箱:拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中

 int a = 10;
        //显示转型
        Integer b = Integer.valueOf(a);
        
        //自动拆箱
        Integer b = a;

        
        Integer c = 10;
        //显示转型
        int d = c.intValue();

        //自动装箱
        int d = c;
我们再了看这样一个代码

 它的结果却是

为什么会这样呢,我们看一下valueoff的源代码

我们发现底层是一个cache的数组 ,[-128, 127]范围内的整型数据装入下标为[0,255]范围内


泛型

就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化

我们都知道Object是所有类的父类,于是我们用它来接受数据类型

我们发现数组array可以存放不同类型的值了,但是如果我们拿一个东西接受的话却发生了报错

 我们发现get方法所返回的值为父类Object,要拿整形或者字符串接受的话需要强制类型转换


1.泛型的定义

这样问题虽然解决了 但是很繁琐,于是就有了泛型!!!

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

泛型类是不可以实例化一个对象的(会报错) 

将上面代码改为泛型类以后,就只可以输入对应的类型,存储数据是也不需要发生强转因为已经指定了类型,指定了什么类型就只能放什么类型(并且尖括号当中只能是引用类型不能是基本类型)


2.擦除机制

在编译的过程当中,将所有的T 替换为 Object 这种机制,我们称为: 擦除机制
Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息,
运行期间没有泛型的概念!!!!!!

3.泛型的上届

当我们在泛型类后面加一个extends(在这里是  扩展的意思),表示类型上边界,即必须是该边界或边界的子类,没有指定类型边界 E,可以视为 E extends Object

我们给T加入一个边界Numbers,于是String不是他的子类立马报错!

4.泛型方法 

有了泛型类,就会有泛型方法,与泛型类大同小异,泛型方法可以声明为 static 的,并且与普通的静态方法是一样的

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

希望对你有帮助