Java基础——集合进阶3

一、ArrayList

1.1 什么是 ArrayList?

ArrayList 是 Java 集合框架中 List 接口的一个 基于动态数组实现的可变长列表

✅ 核心定义:

  • 实现了 ListRandomAccess(支持快速随机访问)、CloneableSerializable 接口
  • 底层使用 Object\[\] 数组存储元素
  • 线程不安全(非同步)
  • 允许存储 null 值,且允许多个 null

自然Collection和List的所有方法实现类ArrayList也可以用。

1.2 ArrayList 的作用与适用场景

主要作用:

  • 提供一个长度可自动增长的有序容器,用于存储和操作一组对象
  • 支持通过索引快速访问、修改、插入、删除元素

✅ 适用场景(高频使用):

  • 需要频繁通过索引访问元素(如 get(i)
  • 元素数量大致已知或变化不大
  • 主要操作是遍历、读取、末尾添加
  • 不需要线程安全(单线程环境)

💡 "90% 的 List 场景,首选 ArrayList!"

1.3 常用方法与代码示例

方法 说明 时间复杂度
add(E e) 在末尾添加元素 O(1)(均摊)
add(int index, E e) 在指定位置插入 O(n)(需移动后续元素)
get(int index) 获取指定索引元素 O(1)
set(int index, E e) 替换指定位置元素 O(1)
remove(int index) 删除指定索引元素 O(n)
remove(Object o) 删除第一个匹配的元素 O(n)
size() 返回元素个数 O(1)
isEmpty() 是否为空 O(1)
contains(Object o) 是否包含某元素 O(n)
indexOf(Object o) 返回首次出现的索引 O(n)
clear() 清空所有元素 O(1)(仅置 null,不释放数组)
java 复制代码
import java.util.*;

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        // 添加
        list.add("Apple");
        list.add("Banana");
        list.add(1, "Cherry"); // 插入到索引1

        // 访问
        System.out.println(list.get(0)); // Apple
        System.out.println(list.size()); // 3

        // 修改
        list.set(0, "Apricot");

        // 删除
        list.remove("Banana"); // 删除值
        list.remove(1);        // 删除索引1

        // 遍历
        list.forEach(System.out::println);
    }
}

1.4 ArrayList集合的底层原理

1.1.1 扩容机制

addAll()方法:可以一次添加List1整个集合中的内容全都添加到List2中。考虑源码的时候要把一次添加一个元素的情况和一次全部添加的情况都要考虑。

注意:底层创建出数组是在添加第一个元素的时候创建的,不是事先创建的。

size的两层含义:表示元素个数、下次存入的位置。

具体的流程详解:

首先在底层,通过空参构造来创建了一个集合,默认初始化长度为0,添加第一个元素"aaa";此时调用add()方法;

把参数"aaa"传递过去,底层又帮我们调用一个add()方法,其中就有三个参数。

参数一:当前要添加的元素;

参数二:集合底层数组的名字;

参数三:集合的长度/当前元素应该存入的位置。

那么调用的add()方法,把三个参数传递给了我们的形参,这个add()方法当中首先会做一个判断,s即你当前要添加的位置,s == elementData.length 是不是等于当前数组的长度,如果是调用grow()方法,grow()其实就是数组的扩容。

grow()方法:会把现有的个数+1(size+1); 然后再去调用有参的构造方法,此时数组长度就变成了1,传递给grow()方法体时,形参(minCapacity)就等于1。

int oidCapacity = elementData.length 记录原来的旧有容量(即0),那么接下来的判断就不满足走else语句,那么后面还要扩容的话就执行if语句里面的代码

调用了Math.max()比较DEFAULT_CAPACITY (10)与 minminCapacity(1)水大;所以new object默认就是10,层层进行返回,默认数组长度就是10,在传入参数之后才创建。

💡 为什么是 1.5 倍?

  • 避免频繁扩容(空间换时间)
  • 比 2 倍更节省内存(减少内存碎片)

1.5 高频面试题(面经精要)

Q1:ArrayList 的默认初始容量是多少?

:JDK 8+ 中,空参构造器创建的 ArrayList 初始容量为 0 ,第一次 add 时扩容为 10

(注意:不是一开始就分配 10!)


Q2:ArrayList 如何扩容?扩容多少?

:当元素数量超过当前数组长度时,会创建一个 1.5 倍原容量的新数组,并将旧数组元素复制过去。若 1.5 倍仍不足,则直接扩到所需大小。


Q3:为什么 ArrayList 查询快、增删慢?

  • 查询快:底层是数组,支持 O(1) 随机访问
  • 增删慢:插入或删除中间元素时,需调用 System.arraycopy() 移动后续所有元素,时间复杂度 O(n)

声明:

分析借鉴于通义AI

以上均来源于B站@ITheima的教学内容!!!

本人跟着视频内容学习,整理知识引用

相关推荐
东南门吹雪4 小时前
JAVA TCP socket编程框架
java·高并发·socket·tcp·nio
xingyuzhisuan4 小时前
缓存命中率提升方案:从 30% 优化至 82% 全流程优化记录
java·开发语言·缓存·ai
郑洁文4 小时前
基于Python的恶意流量监测系统的设计与实现
开发语言·python
AI玫瑰助手4 小时前
Python流程控制:for循环与range函数的搭配使用
开发语言·python·信息可视化
一条泥憨鱼4 小时前
Java开发效率神器:Lombok从入门到精通!
java·后端·学习·开发·lombok
anew___4 小时前
2026年Python爬虫技术完全指南:从入门到实战
开发语言·爬虫·python
Jinkxs4 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
Penfy_Z4 小时前
【Python LLM 调用踩坑】Connection error 终极解决方案!npm 代理导致阿里云通义千问接口连接失败
开发语言·python·npm
星辰徐哥4 小时前
Python AI基础:Python面向对象编程
开发语言·人工智能·python
小宁爱Python4 小时前
Python 依赖管理神器:requirements.txt 从安装到实战全指南
开发语言·python