Java ArrayList 详解

news2024/12/26 20:04:23

Java ArrayList 详解

ArrayList 是 Java 集合框架(Collection Framework)中最常用的类之一,是一种基于动态数组的数据结构,属于 List 接口的实现类。它允许存储重复的元素,有序,支持随机访问,且动态扩容。


1. ArrayList 的特点

  1. 有序ArrayList 按照元素插入的顺序存储,并按索引位置访问。
  2. 允许重复元素:可以存储重复值。
  3. 动态扩容:当容量不足时,会自动扩展存储空间。
  4. 随机访问:通过索引快速访问元素(时间复杂度 O(1))。
  5. 线程不安全ArrayList 不是线程安全的,多个线程同时修改需要手动同步。
  6. 实现接口:实现了 List 接口,同时支持 RandomAccessCloneableSerializable

2. ArrayList 的基本用法

2.1 创建与初始化
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建空的 ArrayList
        ArrayList<String> list = new ArrayList<>();

        // 添加元素
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 输出列表
        System.out.println("List: " + list); // 输出: [Apple, Banana, Cherry]
    }
}
2.2 常用方法
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        
        // 添加元素
        list.add("A");
        list.add("B");
        list.add("C");

        // 获取元素
        System.out.println("Element at index 1: " + list.get(1)); // 输出: B

        // 修改元素
        list.set(1, "Z");
        System.out.println("After update: " + list); // 输出: [A, Z, C]

        // 删除元素
        list.remove("A");
        System.out.println("After removal: " + list); // 输出: [Z, C]

        // 检查是否包含
        System.out.println("Contains B? " + list.contains("B")); // 输出: false

        // 遍历
        for (String s : list) {
            System.out.println(s);
        }

        // 清空列表
        list.clear();
        System.out.println("Is empty? " + list.isEmpty()); // 输出: true
    }
}

3. ArrayList 的常用操作方法

方法描述
add(E e)在列表末尾添加元素。
add(int index, E element)在指定位置插入元素,原位置及后续元素右移。
remove(Object o)删除首次出现的指定元素。
remove(int index)删除指定索引位置的元素。
get(int index)获取指定索引位置的元素。
set(int index, E element)替换指定索引位置的元素为新的元素。
size()返回列表中元素的数量。
contains(Object o)检查列表中是否包含指定元素。
indexOf(Object o)返回元素的首次出现位置,若不存在则返回 -1。
lastIndexOf(Object o)返回元素最后一次出现的位置。
clear()清空列表中的所有元素。
isEmpty()检查列表是否为空。
toArray()将列表转换为数组。
addAll(Collection<? extends E>)添加另一个集合的所有元素到列表。
sort(Comparator<? super E>)对列表进行排序。

4. ArrayList 的工作原理

4.1 动态数组实现
  • 初始容量:创建时,如果未指定容量,ArrayList 默认初始容量为 10
  • 扩容机制:当存储的元素数量超过当前容量时,ArrayList 会动态扩容。扩容后的新容量为 原容量的 1.5 倍
  • 实现细节:底层通过数组 Object[] elementData 来存储元素。

扩容的实现代码:

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量 = 原容量 + 原容量的一半
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    elementData = Arrays.copyOf(elementData, newCapacity);
}
4.2 随机访问
  • 通过数组的索引访问,效率高,时间复杂度为 O(1)
4.3 插入和删除
  • 插入或删除会导致后续元素的移动,时间复杂度为 O(n)

5. ArrayList 的优缺点

5.1 优点
  1. 随机访问效率高:支持通过索引快速访问元素。
  2. 动态扩容:容量不足时自动扩展,无需手动调整。
  3. 实现了丰富的操作方法:提供增删改查、排序等常用操作。
5.2 缺点
  1. 插入和删除效率低:需要移动后续元素,尤其是在中间位置操作时。
  2. 线程不安全:在多线程环境中需要额外同步机制。
  3. 扩容成本高:扩容时需要分配新数组并拷贝旧数组的元素。

6. 线程安全的替代方案

6.1 Vector
  • Vector 是线程安全的 ArrayList 替代方案,但由于每个方法都进行同步,性能较低。
6.2 Collections.synchronizedList
  • 可以通过 Collections.synchronizedList 包装一个线程安全的 ArrayList
import java.util.*;

public class SynchronizedListExample {
    public static void main(String[] args) {
        List<String> list = Collections.synchronizedList(new ArrayList<>());

        list.add("A");
        list.add("B");

        synchronized (list) {
            for (String s : list) {
                System.out.println(s);
            }
        }
    }
}
6.3 CopyOnWriteArrayList
  • 在多线程环境中使用 CopyOnWriteArrayList,每次写操作都会创建新的副本,适用于读多写少的场景。

7. 常见问题与注意事项

  1. 越界异常

    • 尝试访问不存在的索引位置会抛出 IndexOutOfBoundsException
    list.get(10); // 若列表长度不足,抛异常
    
  2. 性能问题

    • 插入、删除操作在列表越靠后的位置,性能越高。
    • 遍历时,建议使用增强型 for 循环或迭代器。
  3. 多线程环境

    • ArrayList 是非线程安全的,多线程操作时需显式同步。

8. 总结

特性描述
实现结构动态数组,支持随机访问,扩容按 1.5 倍增长。
线程安全性非线程安全,需要显式同步或使用线程安全的替代方案。
性能读取效率高(O(1)),插入和删除效率低(O(n))。
适用场景适合需要频繁读取元素的场景,不适合高频插入或删除场景。

ArrayList 是 Java 中灵活且高效的动态数组实现,在开发中广泛应用于需要存储有序、可重复数据的场景。理解其特性和工作原理,合理使用它,能够显著提升程序的性能和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细MacBook Pro(M1)配置GO语言环境(图文超详细版)

前提 当我第一次使用MacBook配置Go语言环境时&#xff0c;网上的资料错综复杂&#xff0c;部分资料对于第一次使用MacBook的小白们非常不友好&#xff0c;打开终端时&#xff0c;终端的位置对应的访达中的位置不是很清楚&#xff0c;因此才有了这篇文章&#xff0c;该文章通过…

单端和差分信号的接线法

内容来源&#xff1a;【单端信号 差分信号与数据采集卡的【RSE】【 NRES】【 DIFF】 模式的连接】 此篇文章仅作笔记分享。 单端输入 单端信号指的是输入信号由一个参考端和一个信号端构成&#xff0c;参考端一般是地端&#xff0c;信号就是通过计算信号端口和地端的差值所得…

前端开发 之 15个页面加载特效中【附完整源码】

前端开发 之 15个页面加载特效中【附完整源码】 文章目录 前端开发 之 15个页面加载特效中【附完整源码】八&#xff1a;圆环百分比加载特效1.效果展示2.HTML完整代码 九&#xff1a;毒药罐加载特效1.效果展示2.HTML完整代码 十&#xff1a;无限圆环加载特效1.效果展示2.HTML完…

【H2O2|全栈】Node.js与MySQL连接

目录 前言 开篇语 准备工作 初始配置 创建连接池 操作数据库 封装方法 结束语 前言 开篇语 本节讲解如何使用Node.js实现与MySQL数据库的连接&#xff0c;并将该过程进行函数封装。 与基础部分的语法相比&#xff0c;ES6的语法进行了一些更加严谨的约束和优化&#…

spark-sql配置教程

1.前期准备 &#xff08;1&#xff09;首先要把hadoop集群&#xff0c;hive和spark等配置好 hadoop集群&#xff0c;hive的配置可以看看这个博主写的博客 大数据_蓝净云的博客-CSDN博客 或者看看黑马程序员的视频 黑马程序员大数据入门到实战教程&#xff0c;大数据开发必…

【网络安全】网站常见安全漏洞 - 网站基本组成及漏洞定义

文章目录 引言1. 一个网站的基本构成2. 一些我们经常听到的安全事件3. 网站攻击者及其意图3.1 网站攻击者的类型3.2 攻击者的意图 4. 漏洞的分类4.1 按来源分类4.2 按危害分类4.3 常见漏洞与OWASP Top 10 引言 在当今的数字化时代&#xff0c;安全问题已成为技术领域不可忽视的…

【最新免费PPT制作并下载】Kimi PPT助手:智能化演示文稿生成,职场效率的革命性提升

最新免费PPT制作方法在这里&#xff01;下面我想向大家介绍一款能够极大提升我们工作效率的工具——Kimi PPT助手。 Kimi PPT助手&#xff1a;智能化演示文稿生成 Kimi PPT助手是由Moonshot AI推出的一款革命性产品&#xff0c;它通过人工智能技术&#xff0c;实现了PPT的一键…

黑马微服务开发与实战学习笔记_MybatisPlus_P1介绍与快速入门

系列博客目录 文章目录 系列博客目录MybatisPlus介绍快速入门Part1:入门案例Part1.1:MyBatis项目Part1.2:实现MP Part2:常见注解Part2.1:约定Part2.2:常见注解 Part3:常见配置MyBatisPlus使用的基本流程是什么? MybatisPlus介绍 在Mybatis上加了Plus&#xff0c;表示对Mybati…

多模态大语言模型的对比

简介 文章主要对比了包括 VideoLLaMA 2 、CogVLM2-video 、MiniCPM-V等模型 目前主流的多模态视觉问答大模型&#xff0c;大部分采用视觉编码器、大语言模型、图像到文本特征的投影模块 目录 简介1. VideoLLaMA 21.1 网络结构1.2 STC connector具体的架构 2. MiniCPM-V 2.62.…

Docker Compose 和 Kubernetes 之间的区别?

一、简介&#x1f380; 1.1 Docker Compose Docker Compose 是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的快速编排&#xff0c;可以管理多个 Docker 容器组成一个应用。你只需定义一个 YAML 格式的配置文件 docker-compose.yml &#xff0c;即可创建并…

小迪安全笔记 第四十四天 sql盲注 实战利用sql盲注 进行漏洞的利用

sql盲注的分类 什么是盲注 就是我们什么也不知道的情况下进行的注入 前边的注入 都是简单的注入 我们猜测 数据类型 之后 可以直接 union 去查 这种情况多用于 数据库增删查改中的 查 bool盲注也用于查 这个的情况的就是我们前边都试了 没有用 就需要…

FFmpeg:强大的音视频处理工具指南

FFmpeg&#xff1a;强大的音视频处理工具指南 1. FFmpeg简介2. 核心特性2.1 基础功能2.2 支持的格式和编解码器 3. 主要组件3.1 命令行工具3.2 开发库 4. 最新发展5. 安装指南5.1 Windows系统安装5.1.1 直接下载可执行文件5.1.2 使用包管理器安装 5.2 Linux系统安装5.2.1 Ubunt…

Cursor+Devbox AI开发快速入门

1. 前言 今天无意间了解到 Cursor 和 Devbox 两大开发神器,初步尝试以后发现确实能够大幅度提升开发效率,特此想要整理成博客以供大家快速入门. 简单理解 Cursor 就是一款结合AI大模型的代码编辑器,你可以将自己的思路告诉AI,剩下的目录结构的搭建以及项目代码的实现均由AI帮…

MySQL——操作

一.库的操作 1.基本操作 创建数据库 create database 数据库名称; 查看数据库 show databases; 删除数据库 drop database 数据库名称; 执行删除之后的结果: 数据库内部看不到对应的数据库 对应的数据库文件夹被删除&#xff0c;级联删除&#xff0c;里面的数据表全部被删…

【Python系列】使用 `psycopg2` 连接 PostgreSQL 数据库

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

MacOS安装sshfs挂载远程电脑硬盘到本地

文章目录 sshfs简介sshfs安装下载安装macFUSE安装sshfs sshfs使用注意事项 sshfs简介 SSHFS&#xff08;SSH Filesystem&#xff09;是一种基于FUSE&#xff08;用户空间文件系统&#xff09;的文件系统&#xff0c;它允许你通过SSH协议挂载远程文件系统。使用SSHFS&#xff0…

数据结构---链表(2)---双向链表

链表(1)中讲过了在OJ题中出现很多并且能作为一些复杂数据结构子结构的不带头单向不循环链表&#xff0c;下面讲解应用很广很实用的带头双向循环链表。 三、双向链表---DoublyLinkedList 演示带头双向循环链表(实用)。 带头--->不需要对空链表继续单独判断&#xff1b;循环…

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:智行无忧停车场管理系统(前后端源码 + 数据库 sql 脚本)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 项目介绍 1.1 项目功能 2.0 用户登录功能 3.0 首页界面 4.0 车辆信息管理功能 5.0 停车位管理功能 6.0 入场登记管理功能 7.0 预约管理功能 8.0 收费规则功能 9.0…

【text2sql】低资源场景下Text2SQL方法

SFT使模型能够遵循输入指令并根据预定义模板进行思考和响应。如上图&#xff0c;、 和 是用于通知模型在推理过程中响应角色的角色标签。 后面的内容表示模型需要遵循的指令&#xff0c;而 后面的内容传达了当前用户对模型的需求。 后面的内容代表模型的预期输出&#xff0c;也…

MongoDB安装|注意事项

《疯狂Spring Boot讲义》是2021年电子工业出版社出版的图书&#xff0c;作者是李刚 《疯狂Spring Boot终极讲义》不是一本介绍类似于PathVariable、MatrixVariable、RequestBody、ResponseBody这些基础注解的图书&#xff0c;它是真正讲解Spring Boot的图书。Spring Boot的核心…