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

相关推荐
hanbr1 小时前
Qt:事件处理与绘图详解
开发语言·数据库·qt
luck_bor1 小时前
File 类核心笔记
java·前端·算法
ZC跨境爬虫1 小时前
模块化烹饪小程序开发日记 Day2:全局配置与 tabBar 实现
java·前端·javascript·微信小程序·html·notepad++
cen__y1 小时前
Linux知识点复习总结(2)
linux·运维·服务器·c语言·开发语言
方便面不加香菜1 小时前
C++ 日期类的实现
开发语言·c++
雁迟1 小时前
第五章:条件判断与分支语句
开发语言·r语言
victory04311 小时前
找实习也是在找自己
java·服务器·前端
geovindu2 小时前
go: Monitor Pattern
开发语言·后端·设计模式·golang·监控模式
摇滚侠2 小时前
MySQL 面试题 真正的 offer 偏方 Java 基础 Java 高级
java·数据库·mysql