首页 > 其他分享 >ArrayList底层原理

ArrayList底层原理

时间:2024-07-26 17:27:47浏览次数:12  
标签:删除 ArrayList 元素 线程 数组 操作 原理 底层

1. ArrayList 的基本结构

  ArrayList 内部使用一个 Object 类型的数组 elementData 来存储所有的元素。数组的长度可以动态调整。

2. 初始容量和扩容机制

  • 初始容量:当使用无参构造创建一个 ArrayList 实例时会在底层创建一个默认长度为0的数组,可以通过添加参数指定一个初始容量。添加第一个元素时,底层会创建一个新的长度为10的数组。
  • 扩容机制:当添加元素导致数组满时ArrayList 会创建一个新数组,新数组的容量通常是旧数组容量的 1.5 倍。

3. 关键操作的实现

    添加元素 (add())
  • 如果 ArrayList 的容量不足以容纳新元素,那么会触发扩容操作。
  • 新元素被添加到数组的末尾。
  • 扩容操作涉及到创建一个新的数组并将旧数组的内容复制到新的数组中。
  • 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准

        例如:初始长度为10的arraylist添加100个数据,那新数组长度为100,

                   初始长度为10且arraylist中有10个数据,那新数组长度为110。

    删除元素 remove()
  • 删除操作会涉及将删除位置之后的所有元素向前移动一位,以填补被删除元素留下的空缺。
    获取元素 get()
  • 这是一个快速的操作,因为它只需要通过索引访问数组即可。
  • 时间复杂度为 O(1)。
    设置元素 set()
  • 类似于获取操作,设置操作只需要更新特定索引处的元素。
  • 时间复杂度为 O(1)。

4. 缩容的细节

  • 缩容ArrayList 默认不会自动进行缩容。这是因为缩容可能会带来额外的性能开销,特别是在频繁添加和删除元素的情况下。一般情况下,当数组中的元素数量远小于数组的实际容量时,才考虑进行手动缩容。

源码:

public void trimToSize() {
    modCount++;
    //如果 size 小于 elementData.length,则表明存在多余的空间。
    if (size < elementData.length) {
    //使用 Arrays.copyOf 方法创建一个新数组,其大小等于当前 size。
        elementData = (size == 0)
        ? EMPTY_ELEMENTDATA
        : Arrays.copyOf(elementData, size);
    }
}

5. 线程安全性

  • ArrayList 本身不是线程安全的。如果你需要在一个多线程环境中使用 ArrayList,你需要自己负责同步或者使用 Collections.synchronizedList 来获得一个线程安全的视图。

什么是线程安全性?icon-default.png?t=N7T8https://blog.csdn.net/m0_61160520/article/details/140719110?spm=1001.2014.3001.5502

6. 性能特点

  • 读取操作:由于 ArrayList 是基于数组实现的,因此随机访问非常快,时间复杂度为 O(1)。

        "随机访问"(Random Access)是指能够直接访问数据结构中的任意元素,而无需从头开始逐个遍历。这种访问方式在基于数组的数据结构中非常常见

  • 插入/删除操作:这些操作涉及到元素的移动,因此时间复杂度通常为 O(n)。特别是对于数组中间的插入或删除操作,需要移动大量的元素。

额外:

Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合

 ArrayList 特点:

  1. 动态数组
    • ArrayList 使用动态数组作为底层数据结构,这意味着它的大小不是固定的。
    • 当数组空间不足时,ArrayList 会自动扩展容量,通常是将容量增加到原来的 1.5 倍左右。
  2. 快速随机访问
    • 由于 ArrayList 使用数组存储元素,可以通过索引直接访问元素,因此支持快速随机访问。
    • 根据索引访问元素的时间复杂度为 O(1),即常量时间。
  3. 增删操作较慢
    • 插入或删除元素时,可能需要移动数组中的其他元素。
    • 对于插入操作,如果插入位置在数组中间,则需要将插入点之后的所有元素向后移动一位。
    • 对于删除操作,如果删除位置在数组中间,则需要将删除点之后的所有元素向前移动一位。
    • 这些操作的时间复杂度通常为 O(n),其中 n 是数组中元素的数量。
  4. 线程不安全:
    • 默认情况下,ArrayList 的实例不是线程安全的。
    • 如果需要在多线程环境中使用 ArrayList,可以使用 Collections.synchronizedList 方法将其包装成线程安全的形式。
  5. 实现了 List 接口中定义的所有方法:还提供了 trimToSize()方法来操作内部数组的大小。
  6. 可存储任何类型的对象:包括 null 值。

标签:删除,ArrayList,元素,线程,数组,操作,原理,底层
From: https://blog.csdn.net/m0_61160520/article/details/140715486

相关文章

  • 【Git学习】概念+原理+常用命令(简洁,快速上手)
    本篇文章是我看完尚硅谷视频后作的总结,分享一下学习笔记。        软件配置管理(SCM)是指通过执行版本控制、变更控制的规程,以及使用合适的配置管理软件来保证所有配置项的完整性和可跟踪性。配置管理是对工作成果的一种有效保护        版本控制:软件版本,......
  • ceph数据重构原理
    本文分享自天翼云开发者社区《ceph数据重构原理》,作者:x****n在分布式存储系统Ceph中,硬盘故障是一种常见问题。为了保证数据安全,当发生硬盘故障后,分布式存储系统会依据算法对故障硬盘上的数据进行数据重构及转储。和一般分布式系统一样的是,Ceph同样使用多副本机制来保证数据的高......
  • 实时云渲染的技术原理是什么?哪个实时云渲染系统更好?
    实时云渲染的技术原理:实时云渲染是一种基于服务器GPU云计算资源来实现云端实时渲染终端轻量化交互的技术,通常被应用到需要高性能算力进行图形渲染的场景中,比如数字孪生、虚拟仿真、三维可视化、云游戏等行业。实时云渲染技术的应用流程是通过实时云渲染平台,将大型应用及3D内容......
  • 在K8S中,hpa原理是什么?
    在Kubernetes(K8S)中,HorizontalPodAutoscaler(HPA)是一种自动扩缩容机制,它可以根据预定义的指标自动调整Pod的数量。HPA的主要目的是确保应用程序能够根据实际负载自动伸缩,从而提高资源利用率和系统的弹性。1.HPA的工作原理定义目标指标:用户首先需要定义扩缩容......
  • Redis原理与应用
    一为什么使用redis?1.支持高可用,3.0集群2.丰富的数据类型3.完全内存操作,速度快,支持持久化4.存储数据大,单个key和value可以存储到1G二Redis的持久化方式?redis持久化方式有RDB和AOF  ,RDB是方式是每过几秒保存的是redis数据的快照,但是可能会丢数据,AOF 保存的是所有在......
  • 线程的核心原理
    线程调度模型1分时调度模型:系统平均分配CPU时间片,所有线程轮流占用CPU.2抢占式调度模型:系统按照线程优先级来分配CPU时间片,优先级高的线程获取CPU执行时间相对多一些.线程的优先级Thread类里的这个属性privateintpriority代表线程的优先级.优先级值的范围为1-10.......
  • ScrollView实现原理分析
    ScrollView是Android中用于实现单向滚动功能的布局容器。它只能容纳一个子视图,并且能够使这个子视图在垂直方向(默认)或水平方向上滚动。下面我们将结合源码来分析ScrollView的实现原理。1.ScrollView类定义ScrollView继承自FrameLayout,这意味着它本身是一个布局容器,......
  • ViewPager2实现原理分析
    ViewPager2 是Android开发中用于实现水平滑动视图的组件,它是 ViewPager 的一个改进版,提供了更多的功能和更好的性能。下面,我们将结合源码来简要分析 ViewPager2 的实现原理。1.基本架构ViewPager2 的主要架构基于 RecyclerView,它利用了 RecyclerView 的滚动、布......
  • 智能音箱的工作原理
    智能音箱的工作原理主要涉及到硬件和软件两个层面的协同工作,以及多个关键技术环节的配合。以下是对智能音箱工作原理的详细解析:一、硬件层面智能音箱的硬件组成通常包括主控芯片、麦克风阵列、扬声器、Wi-Fi模块和电源等部分。主控芯片:作为智能音箱的“大脑”,负责控制整个......
  • java的跨平台原理
    java的跨平台原理:Java跨平台的原理主要是通过Java虚拟机(JVM)来实现的。为啥需要跨平台:不同平台的机器码是不兼容的。在编译原理中,我们知道编译器将源代码翻译成特定平台的机器码,这样程序就可以在特定平台上运行。然而,不同平台的机器码是不兼容的,这就导致了跨平台的困难。......