Java集合框架之ArrayList解析

news/2025/2/21 7:52:41

目录

一、ArrayList概述

二、优缺点分析

三、底层数据结构

四、源码分析ArrayList初始化容量

五、源码分析ArrayList扩容策略

六、ArrayList集合源码分析

1. 属性分析

2. 构造方法分析

无参构造方法

指定初始容量的构造方法

传入集合的构造方法

3. 添加元素

add(E e) 方法

add(int index, E element) 方法

4. 修改元素

set(int index, E element) 方法

5. 插入元素

6. 删除元素

remove(int index) 方法

remove(Object o) 方法

七、Vector

1. 底层结构与线程安全

2. 初始容量与扩容策略

3. 为何逐渐被弃用?


一、ArrayList概述

ArrayList 是Java集合框架中最常用的类之一,基于动态数组实现,继承自 AbstractList 并实现了 List 接口。它提供了高效的元素访问能力,适合频繁查询少随机增删的场景。本文将从源码层面深入分析其设计原理、性能特点及最佳实践。

二、优缺点分析

优点:

高效随机访问:通过下标直接访问元素,底层是数组,因此根据下标查找元素的时间复杂度是O(1)。因此检索效率高。

list.get(3); // 直接访问索引3处的元素

尾部操作高效:在数组末尾添加或删除元素时,时间复杂度为 O(1)(无需移动元素)。

缺点:

随机增删效率低:在数组中间插入或删除元素时,需移动后续元素,时间复杂度为 O(n)。不过只要数组的容量还没满,对末尾元素进行增删,效率不受影响

list.add(2, "Java"); // 插入到索引2,后续元素后移

内存浪费:数组容量可能大于实际元素数量,占用额外内存

三、底层数据结构

ArrayList 的核心是一个 Object[] elementData 数组,所有元素按插入顺序依次存储。数组的连续内存特性使得其支持通过下标快速访问元素(时间复杂度 O(1))。

// JDK 11源码片段
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    transient Object[] elementData; // 存储元素的数组
    private int size;              // 实际元素个数
}

四、源码分析ArrayList初始化容量

在 Java 中,ArrayList 类有多个构造方法,不同构造方法对初始容量的处理不同:

  • 无参构造方法:初始容量为 0,当第一次调用 add 方法时,容量会被初始化为 10。
  • 带初始容量参数的构造方法:使用指定的初始容量。
  • 带集合参数的构造方法:初始容量为传入集合的大小。

下面是 ArrayList 无参构造方法的源码:

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

其中 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空数组:

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

无参构造:创建一个空数组(初始容量为0),首次调用 add() 方法时扩容至 10

List<String> list = new ArrayList<>(); // elementData = {}
list.add("A"); // 首次扩容,容量变为10

当第一次调用 add 方法时,会触发扩容逻辑,将容量初始化为 10,相关源码如下:

private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity <= 0) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

其中 DEFAULT_CAPACITY 的值为 10:

private static final int DEFAULT_CAPACITY = 10;

五、源码分析ArrayList扩容策略

  • 触发条件:当元素数量 size 超过数组长度 elementData.length

  • 扩容规则:新容量为原容量的 1.5倍(通过位运算优化:newCapacity = oldCapacity + (oldCapacity >> 1))。

  • 扩容实现:调用 Arrays.copyOf() 创建新数组并拷贝原数据。


http://www.niftyadmin.cn/n/5860491.html

相关文章

测绘未来3-5年的发展

一、行业现状评价 1.1竞争格局多元化 传统测绘企业(如超图软件、航天宏图)与新兴技术企业(如无人机测绘服务商)共同竞争,同时互联网巨头(百度、高德)跨界布局,进一步加剧市场分化。2024年多家头部企业净利润大幅下滑,反映出行业盈利压力与转型紧迫性。 1.2.技术门…

处理哈希冲突

有时候哈希表⽆论选择什么哈希函数都⽆法避免冲突&#xff0c;那么插⼊数据时&#xff0c;如何解决冲突呢&#xff1f;主要两种⽅法&#xff0c;线性探测法和链地址法&#xff0c;这篇先做原理描述&#xff0c;下篇实现代码模拟 一、线性探测 发生冲突的位置开始&#xff0c;依…

常用的性能优化方法和技巧

常用的性能优化方法和技巧 前端性能优化 减少HTTP请求&#xff1a;就好比你去超市买东西&#xff0c;每次请求就像你跑一趟超市。去的次数越多&#xff0c;花在路上的时间就越多。所以把多个小的资源&#xff0c;像图片、脚本这些&#xff0c;合并成一个大的&#xff0c;就能…

#渗透测试#批量漏洞挖掘#畅捷通T+远程命令执行漏洞

免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章读。 目录 一、漏洞概况 二、攻击特征 三、应急处置…

selenium爬取苏宁易购平台某产品的评论

目录 selenium的介绍 1、 selenium是什么&#xff1f; 2、selenium的工作原理 3、如何使用selenium&#xff1f; webdriver浏览器驱动设置 关键步骤 代码 运行结果 注意事项 selenium的介绍 1、 selenium是什么&#xff1f; 用于Web应用程序测试的工具。可以驱动浏览…

详解同为科技桌面PDU系列产品特点

同为科技的桌面PDU系列产品是依据自身在电气联接领域25年专业积累并精心设计&#xff0c;产品采用模块化结构&#xff0c;实现各种功能、输出插口、输入方式可根据用户需求以模块组合的方式构建定制化产品。 桌面PDU产品特点 工业级材质和结构设计 桌面PDU系列产品采用一体成…

计算机专业知识【局域网(LAN)标准与国际标准化组织(ISO)]

在计算机网络领域&#xff0c;局域网&#xff08;LAN&#xff09;是一种常见且重要的网络类型。很多人会疑惑 LAN 的国际标准是否由国际标准化组织&#xff08;ISO&#xff09;制定&#xff0c;下面我们就来详细探讨这个问题&#xff0c;并介绍 ISO 制定过的一些重要标准。 一…

多进程(1)

1.多任务&#xff1a;让系统同时具备处理多个任务的能力。 2.方法&#xff1a;多进程&#xff1b;多线程&#xff1b; 3.进程&#xff1a;正在执行的程序&#xff0c;需要消耗cpu和内存&#xff0c;一个动态执行的过程。 4.进程和程序的区别&#xff1a; &#xff08;1&…