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 这个成员变量来直接判断里面是不是空的。

相关推荐
贺国亚4 分钟前
Spring-AI与LangChain4j
java·人工智能·spring
Cloud_Shy6185 分钟前
解读《Effective Python 3rd Edition》:从练气到老魔(第三章 Item 21 - 24)
开发语言·人工智能·笔记·python·迭代器模式
多彩电脑9 分钟前
Lua中的元表里的__index和__newindex
开发语言·lua
野生技术架构师18 分钟前
2026 Java面试宝典(春招/社招/秋招通用):没有前言,只有答案,直接开背
java·开发语言·面试
mN9B2uk1723 分钟前
数据库的约束简介
java·数据库·sql
AI人工智能+电脑小能手27 分钟前
【大白话说Java面试题 第99题】【Mysql篇】第29题:如何选择合适的分布式主键方案?
java·数据库·分布式·mysql·面试
极光代码工作室31 分钟前
基于SpringBoot的任务管理系统
java·springboot·web开发·后端开发
人道领域1 小时前
【LeetCode刷题日记】131.分割回文串,动态规划优化
java·开发语言·leetcode
z落落1 小时前
C# 接口 interface (多接口实现、类+接口、成员重名)
java·开发语言
发际线向北1 小时前
0x05 深入了解JVM虚拟机(JVM方法调用 -Ⅰ)
java