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

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,不释放数组)
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)); // AppleSystem.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的教学内容!!!

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

http://www.dtcms.com/a/585764.html

相关文章:

  • Ascend C 编程模型揭秘:深入理解核函数与任务并行机制
  • 算法题——002
  • 佛山微信网站开发易语言网站开发教程
  • 从零搭建PyTorch计算机视觉模型
  • 培训课程网站建设淮阳 网站建设
  • 服务器为何成为网络攻击的“重灾区“?
  • Linux rcu机制
  • ES 总结
  • j集团公司的网站建设石家庄百度推广优化排名
  • k8s-node-NotReady后如何保证服务可用
  • 5-GGML:看一下CUDA加法算子!
  • 做网站优化需要做哪些事项wordpress圆圈特效
  • 濮阳网站建设费用网站怎样做外链
  • Docker 部署 Java 项目实践
  • Git push/pull 避坑指南:什么时候加 origin?什么时候不用加?
  • Ubuntu22.04系统中各文件目录的作用
  • 49_AI智能体核心业务之使用Flask蓝图模块化AI智能体服务:构建可维护的RESTful API
  • 网站建设教程数据库网站开发兼职成都
  • 网站 空间 下载行情网免费网站大全
  • 深度学习实战(基于pytroch)系列(五)线性回归的pytorch实现
  • 玩转Rust高级应用. ToOwned trait 提供的是一种更“泛化”的Clone 的功能,Clone一般是从T类型变量创造一个新的T类型变量
  • 11.8 脚本网页 推箱子
  • 网站建设要钱么深圳一百讯网站建设
  • [Java算法] 双指针(1)
  • 江苏省建设厅网站官网湖南做网站最厉害的公司
  • 杭州家具网站建设方案郑州app开发价格
  • gdb调试命令和GDB 到 LLDB 命令映射
  • 【CUDA笔记】02 CUDA GPU 架构与一般的程序优化思路(上)
  • 198种组合算法+优化XGBoost+SHAP分析+新数据预测!机器学习可解释分析,强烈安利,粉丝必备!
  • 东莞做网站要多少钱安顺建设局网站官网