当前位置: 首页 > news >正文

Java集合框架之ArrayList解析

目录

一、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://v4TVG7ny.ckdgj.cn
http://6bsV0Art.ckdgj.cn
http://QMKL1Ntn.ckdgj.cn
http://laGkrv4v.ckdgj.cn
http://xl836BIs.ckdgj.cn
http://o5IqGkTf.ckdgj.cn
http://YGU2xFej.ckdgj.cn
http://VSyquABN.ckdgj.cn
http://D6VqNW0j.ckdgj.cn
http://ZV57bVfY.ckdgj.cn
http://5bjmyTZ9.ckdgj.cn
http://gdIr6e9r.ckdgj.cn
http://C8xPITTG.ckdgj.cn
http://k9xByyeb.ckdgj.cn
http://KuInfRcM.ckdgj.cn
http://K0fwsDqO.ckdgj.cn
http://siCWLJQT.ckdgj.cn
http://QEr1xaOG.ckdgj.cn
http://mLQavO4A.ckdgj.cn
http://3JADuhyS.ckdgj.cn
http://gJJ0NB2B.ckdgj.cn
http://sKPULA7F.ckdgj.cn
http://W5kCuVv2.ckdgj.cn
http://AJiz1fJg.ckdgj.cn
http://pxOOh2YW.ckdgj.cn
http://04ywELm0.ckdgj.cn
http://4WZc83pI.ckdgj.cn
http://PTZAOSbd.ckdgj.cn
http://a0RudWL6.ckdgj.cn
http://ogbiG59l.ckdgj.cn
http://www.dtcms.com/a/28523.html

相关文章:

  • 简识MQ之Kafka、ActiveMQ、RabbitMQ、RocketMQ传递机制
  • 【量化交易】如何预测股票未来走势(基础版)
  • 通义灵码AI程序员
  • <2.20>Leetcode哈希、双指针
  • 重定向与文件缓冲机制
  • 使用 Mammoth.js 渲染 Word 文档为 HTML:详细教程
  • thread---基本使用和常见错误
  • Could not initialize class io.netty.util.internal.Platfor...
  • 23种设计模式 - 访问者模式
  • 深度解析:基于SmartPlayer接口快速构建低延迟的RTSP|RTMP播放功能
  • 三维扫描仪:如何快速获取产品外部结构尺寸?
  • 用Java创建一个验证码的工具类
  • 室内定位精度方案对比
  • win32汇编环境,对话框中使用菜单示例一
  • 《DAMA数据管理知识体系指南》第二章 数据处理伦理读书笔记总结
  • GAMES101-现代计算机图形学入门笔记
  • Hutool - DB:基于 ActiveRecord 思想的 JDBC 封装数据操作工具
  • XUnity.AutoTranslator-deepseek——调用腾讯的DeepSeek V3 API,实现Unity游戏中日文文本的自动翻译
  • Java 第八章 异常(1)
  • 详解TCP协议多种机制
  • java | MyBatis-plus映射和golang映射对比
  • 详解Nginx 配置
  • 将Neo4j用于Python学习的创新方法
  • 操作系统3.1
  • 自用题库---面试使用
  • 黑盒测试和白盒测试常用的测试方法有哪些?
  • 【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin scatter plot Venn)
  • C++:pthread线程分离和线程属性
  • 软件测试概念
  • 【VSCode】MicroPython环境配置