基础数据结构 -- 数组

目录

1. 数组

1.1 简介

1.2 特点

1.3 优缺点

2. 动态数组 -- ArrayList

2.1 简介

2.2 与数组区别

2.3 ArrayList细节

2.3.1 接口细节

2.3.2 扩容细节

1. add()源码

2. grow()源码

3 总结


1. 数组

1.1 简介

数组是一种基础且重要的数据结构,对于每一种编程语言都有着不可或缺的作用,它用于存储一系列按顺序排列的同类型数据。

int[] a = new int[5]{1,2,3,4,5};

1.2 特点

特点:

  • 数组是线性表的一种实现方式,它使用连续的内存空间来存放数据。
  • 数组中的元素可以通过索引(或称为下标)进行访问,这些索引通常从0开始计数,并按照元素的存放顺序依次递增。
  • 在数组中,每个元素所占用的存储空间大小是固定的,并且所有的元素类型都是一致的。

1.3 优缺点

优点:

  • 访问高效:由于数组采用连续内存存储,可以直接通过索引快速定位到任意一个元素,因此访问速度非常快。
  • 操作简单:对于基本的读取操作来说,数组的操作非常简单明了。

缺点:

  • 动态操作效率低:数组的大小在初始化时需要固定,因此在不知道数据量的情况下,可能需要频繁地进行数组扩容或缩容操作,这会导致额外的计算和数据迁移开销。
  • 插入和删除操作效率低:与访问操作相比,如果在数组中间位置插入或删除元素,需要移动大量元素以维护连续性,因此效率较低。

2. 动态数组 -- ArrayList

2.1 简介

        由于数组的大小固定的局限性,很多高级语言都会能够动态增长和缩减的数据结构。

2.2 与数组区别

1. 大小

  • 数组(Array)的大小是固定的,一旦创建后就无法改变。
  • ArrayList 的大小是动态的,可以根据需要增加或减少元素。

2. 类型

  • 数组可以包含基本类型和对象类型。
  • ArrayList 只能包含对象类型,对于基本类型,需要使用自动装箱转化为包装类后才能存储。

3. 使用场景

  • 如果数据量大小固定不变,可以使用数组,因为它有较小的内存开销。
  • 如果数据量大小需要动态变化,则应使用 ArrayList,因为它提供了更多的方法和灵活性来管理集合数据。

2.3 ArrayList细节

2.3.1 接口细节

ArrayList继承了 AbstractList 类,支持迭代器Iterator。

ArrayList实现了 RandomAccess 接口,它可以快速地通过索引访问元素,这使得它在随机访问时非常高效。

ArrayList实现了 List 接口,可进行列表的相关操作。

ArrayList实现了 Cloneable 接口,可实现克隆。

ArrayList实现了 Serializable 接口,可支持序列化,能通过序列化去传输。

2.3.2 扩容细节

ArrayList底层是通过数组实现的,要实现动态添加功能,无法避免的就是空间不够,则需要扩容。但如果每次添加数据时都进行扩容,会浪费很多性能。接下来就追溯Java源码,来聊聊ArrayList是如何扩容的。

1. add()源码

在添加前会判断是否能将数据放入数组,如果不能,将执行grow()进行扩容。

2. grow()源码

步骤有三:

  1. 确定所需大小(size + 1)
  2. 生成新的数组,大小为 老数组大小 + 老数组的一半
  3. 将老数组拷贝到刚刚新生成的数组中,返回数组

扩容规则:

        新数组大小 = 老数组大小 + 老数组大小的一半

这种扩容方法在c++的vector的也有体现,在vector中称这种方法为半倍扩容法

        注:由于每次扩容都会拷贝一次数组,如果数据量很大,就将面临频繁扩容的问题。这样添加数据时会有很多时间都在拷贝数组,这样会很占内存,效率十分低下。所以当数据量很大,就需要通过指定初始容量的构造方法来避免频繁扩容。

3 总结

        数组是计算机科学中一种基本的、重要的数据结构,用于存储一系列按顺序排列且类型相同的数据元素

  1. 定义和特性

    • 数组由固定数量的内存位置组成,每个位置可以存储一个特定类型的值(例如整数、浮点数或字符)。
    • 这些内存位置通过连续的索引进行访问,通常从0开始编号。
    • 数组在内存中是连续分配的,这使得元素可以通过其索引快速访问。
  2. 优势

    • 高效的随机访问:可以直接通过索引在常数时间内访问任意元素。
    • 内存效率:由于数组在内存中连续存储,它们通常比链表等其他数据结构更节省空间。
  3. 高级语言中的实现

    • 在像Java这样的高级语言中,数组被赋予了额外的属性和方法,如自动内存管理和各种便捷的操作方法。
    • Java中的ArrayList是一种类似于数组的数据结构,它允许动态调整大小并提供了更多的功能。

        最后,需要注意的是,ArrayList不是线程安全的,因此在多线程环境下使用时需要额外的同步措施。如果需要在多线程环境中使用,可以考虑使用Vector或者Collections工具类中的synchronizedList方法来获取一个同步的List。

  • 27
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值