揭开数组的面纱:从底层到Java的ArrayList

目录

数组的概念

低效的插入和删除操作

java容器类ArrayList


  • 数组的概念

1.数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据

2.概念解释:

①线性表:数据排列成一条线一样的结构,每个线性表上的数据最多只有前和后两个方向。其他常见的线性表还包括链表、队列、栈等。

②非线性表:如树、堆、图等,数据之间不是简单的前后关系。

③连续的内存空间:这意味着,数组的第一个元素和最后一个元素是相邻的,中间没有任何空隙。正因为这个特性,我们可以通过数组的基地址快速地计算出任意一个元素的内存地址。例如:拿一个长度为5的int类型的数组int[] a = new int[5] 来举例,假设一个int需要4字节存储,计算机给这个数组分配了一块连续内存空间 1000~1019。当我们随机访问数组中的某个元素时,首先他会通过数组的基地址(这里是1000)快速地计算出这个元素的内存地址。比如我们要找第4个元素。

那么第四个元素的地址 = 基地址 + 要找的元素的索引×4 = 1000 + 3×4 = 1012

所以,数组支持随机访问,随机访问的时间复杂度是O(1)。

④相同类型的数据:我们只能存储一种数据类型。例如,如果我们定义了一个整数数组,那么这个数组中的每个元素都必须是整数。这是因为,连续的内存分配要求每个元素占用相同大小的内存。例如,整数可能占用4字节,而浮点数可能占用8字节。如果数组可以混合存储,那么计算机就不知道每个元素应该使用多少内存了。

  • 低效的插入和删除操作

数组的插入和删除效率低的原因主要与其两个核心特性有关:连续的内存空间和固定的大小

1.连续的内存空间:当你想在数组的中间位置插入一个新元素时,为了保持内存的连续性,你需要移动该位置之后的所有元素以创建空间。同样地,当你删除一个元素时,为了填补产生的空隙,你也需要移动该位置之后的所有元素。这些移动操作会随着被移动的元素数量增加而增加。

2.固定的大小:数组在被创建时大小是固定的。如果数组已满,而我们还想插入更多的元素,那么需要做的不仅仅是插入操作。还需要为新的元素分配一个更大的内存块,然后将旧数组中的所有元素复制到新的位置,最后在新位置上插入新的元素。这个重新分配和复制的过程是非常耗时的

  • java容器类ArrayList

1.容器类能不能完全替代数组?

不能,原生数组可能会比 ArrayList 更高效,特别是在性能敏感的应用中,因为原生数组的存取操作可能比通过 ArrayList 的方法更快,且原生数组避免了额外的对象包装和方法调用开销。但是!!!我们一般用一般ArrayList就够了,除非那些对性能要求比较高的。

2.ArrayList相对于数组的优势是什么?我认为主要有两点:

动态扩容:当 ArrayList 的容量不足以容纳更多的元素时,它可以自动扩容。每次存储空间不够的时候,它都会将空间自动扩容为 1.5 倍大小。但还是建议在创建ArrayList的时候指定好数据的大小,因为扩容操作是比较耗时的。

②自动处理数组插入和删除: 当你要在 ArrayList 的中间位置插入或删除元素时,ArrayList 会自动为你处理必要的元素移动,使得插入和删除操作更加简洁。

总结:一般ArrayList足够用了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值