Java数据结构集合框架(顺序表(ArrayList)的详细解析)(两千字详细解析)

目录

一、线性表

二、顺序表

三、ArrayList简介

四、ArrayList的构造方法

[4.1 指定初始空间的构造方法](#4.1 指定初始空间的构造方法)

[​编辑4.2 不传参数的构造方法](#编辑4.2 不传参数的构造方法)

[4.3 传集合类的构造方法](#4.3 传集合类的构造方法)

四、添加方法

4.1add方法

​编辑

[4.2指定插入函数(add(int index, E element))](#4.2指定插入函数(add(int index, E element)))

4.3扩容函数

1.扩容触发条件:

2.扩容核心逻辑:

五、set()和get()方法

六、删除方法

[​编辑七、size() 和 isEmpty()](#编辑七、size() 和 isEmpty())


一、线性表

线性表 是n个具有相同特性的数据元素的有限序列 。线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表、链表、栈、队列

线性表 在逻辑上是线性结构,也就是说是一条连续的直线。但是在物理结构上不一定是连续 的,线性表在物理上存储时,通常一数据和链式结构的形式存储。

二、顺序表

顺序表 是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般都是使用数组 实现。在数组上完成增删改查操作

三、ArrayList简介

这是java中的源代码,可以清晰的看出它是继承了 AbstractLIst 这个抽象类,实现 了其中的所有方法,并且继承了List......等类,所以里面的函数是非常多的

而且它还是一个线程不安全 的集合,所以在使用的时候效率会比较高 ,是我们经常使用的集合类。

四、ArrayList的构造方法

这是java中的三种构造方法,第一种是给定初始空间大小 的构造方法,第二种是无参数构造 方法,构造出来一个空间为空 的ArrayList,第三种是使用一个集合来初始化新的ArrayList。

4.1 指定初始空间的构造方法

这是 ArrayList指定初始容量 的构造方法,当你传入一个**>0** 的数时,会进入第一个if循环里,直接使用传入的空间大小来进行开辟初始空间

当值 <0 时就会抛出 IllegalArgumentException 这个异常,导致程序异常终止

当值 =0 时会创建出来一个空的顺序表

4.2 不传参数的构造方法

这里不传参数会构造出来一个 的ArrayList出来

4.3 传集合类的构造方法

用一个已有的集合初始化 新的ArrayList ,只要集合里的元素时E的子类/实现类 ,就可以传入,这里有泛型上限 。这里的主要逻辑是 Object\[\] a = c.toArray(); 先把集合c 转化成Object 数组,拿到集合中的所有元素 ,然后把数组长度赋值给size,判断是否为空 ,(排除传入的集合是一个空的集合),如果长度是0 ,就会进入创建一个空的ArrayList集合类。

接下来又会判断传入的集合类是不是ArrayList 类型的,如果是,直接把a 的引用给新创建的ArrayList ,可以节省时间 。如果不是会使用Array.copyOf 做一次数组的拷贝,生成一个新的Object\[\] 赋值给elementData ,防止外部修改原集合影响当前ArrayList

四、添加方法

这是所有添加方法,分别是添加一个元素,和添加所有元素,

4.1add方法

这里添加一个元素,先让count++ ,然后调用add 的函数,把该类里面的数组传进去,还有该添加元素的位置。进入函数之后判断当前是否满了 ,满了就会触发扩容操作 ,然后让数组的末尾 添加该元素,最后再让size++。默认都是尾插法。

4.2指定插入函数(add(int index, E element))

指定函数插入,它就是让指定位置的数据往后覆盖 ,保证指定位置的空间是可以被重新覆盖的。也就是说再插入前,我们需要保证元素的有效性 ,我们需要把指定位置的元素和后面的元素整体往后移动 ,来保证指定位置元素是无效的,这时候直接插入就可以

4.3扩容函数

这段grow 方法,是ArrayList自动扩容机制核心 实现,他根据当前数组容量所需最小容量 ,计算出新的数组长度 ,并通过数组拷贝完成扩容。

1.扩容触发条件:

add() 方法发现底层数组容量不足 以容纳新元素是,会调用grow(int minCapacity) ,其中minCapacity扩容过后 必须满足的最小容量(是当前的size + 1)

2.扩容核心逻辑:

先获取当前底层数组的长度 elementData.length

如果数组已经初始化过(非空数组),会按照1.5倍扩容,通过ArraySupport.newLength 重新计算容量,在使用 Arrays.copyOf 创建一个新数组,把原数组拷贝过去,完成扩容。

如果是空数组(无参数构造创建的ArrayList首次扩容),会直接创建一个长度为10的数组

五、set()和get()方法

修改方法 set(int index, E element) 和获取方法 get(int index)

get 和 set 的时间复杂度都是o(1) 的,因为ArrayList 底层是数组 实现的,而且这里两个方法都需要传递下标来访问,数组使用下标来访问数组元素是o(1)的,所以这两个函数的效率很高

六、删除方法

reomove(int index)(按下表删除) 和 remove(Object o)(按元素删除)

remove(int index) ,按照下标删除这个方法,先判断下标,把该下表后面的元素整体覆盖到前面就完成了修改操作,就像下面这样,我们在这个数组中要删除3这个元素,直接让4,5,6直接来整体往前覆盖就可以把3给清除掉

**remove(Object o),**这个方法会现在数组中找该元素的位置,如果没有就返回false,如果有就返回true,删除策略和上面一样,使用覆盖的方法来删除。

七、size() 和 isEmpty()

size() 获取当前顺序表中元素个数 ,类里面会有一个 size 的成员变量,每次添加 元素会**++** ,remove 会**--** ,就很好的控制了这个size

isEmpty() 也会使用size 这个成员变量来直接判断里面是不是空的。

相关推荐
狼爷11 小时前
吃透 Java Function 接口,搞定 99% 的 Stream 场景
java·函数式编程
祎雪双十Gy15 小时前
从 DataX 的配置加载说起:我用 FastJson2 做了一个轻量级动态配置管理库
java·后端
小锋java123415 小时前
分享一套锋哥原创的SpringBoot4+Vue3宠物领养网站系统
java
考虑考虑19 小时前
Java实现hmacsha1加密算法
java·后端·java ee
掉鱼的猫19 小时前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·spring boot
plainGeekDev20 小时前
广播接收器 → Flow + Lifecycle
android·java·kotlin
plainGeekDev20 小时前
EventBus → SharedFlow
android·java·kotlin
带刺的坐椅20 小时前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
用户37215742613520 小时前
Java 将一个 PPT 文档拆分为多个文件
java
人活一口气1 天前
Spring Boot与AIGC的完美结合:从零搭建智能内容生成平台
java·spring boot·aigc