数据结构-ArrayList

文章目录

  • 1. 线性表
  • 2. 顺序表
  • 3. ArrayList
  • 4. ArrayList的问题以及思考
    • 4.2 增容的性能消耗问题
    • 4.3 空间浪费问题

1. 线性表

线性表(Linear List)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见线性表:顺序表、链表、栈、队列…

线性表在逻辑上是线性结构,也就是连续的一条直线。但是在物理上不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2. 顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表的实现

package myDataStructure.ArrayList;/*** @Author: Author* @CreateTime: 2025-03-18* @Description:*/
public interface SeqList<T> {// 新增元素,默认在数组最后新增void add(T data);// 在 pos 位置新增元素void add(int pos, T data);// 判定是否包含某个元素boolean contains(T toFind);// 查找某个元素对应的位置int indexOf(T toFind);// 获取 pos 位置的元素T get(int pos);// 给 pos 位置的元素设为 valuevoid set(int pos, T value);// 删除第一次出现的关键字keyvoid remove(T toRemove);// 获取顺序表长度int size();// 清空顺序表void clear();
}
package myDataStructure.ArrayList;import java.util.Arrays;/*** @Author: Author* @CreateTime: 2025-03-18* @Description: 支持泛型的动态数组的实现*/
public class MyArrayList<T> implements SeqList<T>{private Object[] array; // 内部使用 Object[] 存储数据,因为 Java 的泛型会在运行时擦除类型信息。private int size;public MyArrayList(){array=new Object[10];}// 动态扩容private void checkCapacity(){if (array.length==size){array=Arrays.copyOf(array,size*2);}}// 添加操作的边界检查private void rangeCheckForAdd(int index) {if (index<0||index>size){throw new IndexOutOfBoundsException("index超出范围");}}// 读取修改操作的边界检查private void rangeCheckForGetAndSet(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("index超出范围");}}@Overridepublic void add(T data) {checkCapacity();array[size]=data;size++;}@Overridepublic void add(int pos, T data) {checkCapacity();rangeCheckForAdd(pos);for(int i=size;i>pos;i--){array[i]=array[i-1];}array[pos]=data;size++;}@Overridepublic boolean contains(T toFind) {if (toFind==null){// 如果 toFind 是null,直接调用 array[i].equals(toFind) 会导致 NullPointerExceptionfor (int i = 0; i < size; i++) {if (array[i] == null) {return true;}}}else {for (int i=0;i<size;i++){if (array[i].equals(toFind)){return true;}}}return false;}@Overridepublic int indexOf(T toFind) {if (toFind == null) {for (int i = 0; i < size; i++) {if (array[i] == null) {return i;}}} else {for (int i = 0; i < size; i++) {if (toFind.equals(array[i])) {return i;}}}return -1;}@Overridepublic T get(int pos) {rangeCheckForGetAndSet(pos);return (T)array[pos];}@Overridepublic void set(int pos, T value) {rangeCheckForGetAndSet(pos);checkCapacity();array[pos]=value;}@Overridepublic void remove(T toRemove) {int pos=indexOf(toRemove);if (pos==-1){return; // 元素不存在,直接返回}for (int i=pos;i<size-1;i++){array[i]=array[i+1];}array[size-1]=null;// 清理最后一个元素size--;}@Overridepublic int size() {return size;}@Overridepublic void clear() {size=0;}public String toString(){StringBuilder sb = new StringBuilder("[");for (int i = 0; i < size; i++) {sb.append(array[i]);if (i < size - 1) {sb.append(", ");}}sb.append("]");return sb.toString();}
}

3. ArrayList

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
图片

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化
  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择CopyOnWriteArrayList
  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

4. ArrayList的问题以及思考

##4.1 插入或删除元素的性能问题(时间复杂度 O(N))

ArrayList 底层是基于数组实现的,插入或删除元素时,所有后续元素需要整体移动,导致时间复杂度为 O(N)。

  • 使用链表(LinkedList
    • 对于频繁插入或删除操作的场景,LinkedList 是更好的选择。
    • LinkedList 是基于双向链表实现的,插入和删除的时间复杂度为 O(1)(只需调整指针),但随机访问的时间复杂度为 O(N)。
    • 适用场景:需要频繁插入或删除的场景,但随机访问较少。
  • 使用 ArrayDeque
    • 如果操作集中在首尾两端,可以使用 ArrayDeque,它支持高效的首尾插入和删除操作。
  • 优化插入/删除的逻辑
    • 如果需要频繁插入或删除,尽量批量操作,而不是逐个操作。例如,先将需要插入的数据存储在临时集合中,最后一次性合并到目标集合。

4.2 增容的性能消耗问题

ArrayList 增容时需要重新分配新空间,并将旧数组的数据拷贝到新数组中,这会带来性能开销。

  • 预估容量,合理初始化 ArrayList 的初始容量

    • 在创建ArrayList时,尽量根据实际需求指定初始容量,避免频繁增容。例如:

      ArrayList<Integer> list = new ArrayList<>(1000);
      

      这样可以减少扩容操作的发生。

  • 使用 ArrayList.ensureCapacity() 方法

    • 如果知道大概需要插入的元素数量,可以在插入数据前调用ensureCapacity()方法手动扩容,避免多次增容。例如:

      list.ensureCapacity(1000);
      
  • 使用其他动态数据结构

    • 如果扩容的性能开销成为瓶颈,可以考虑使用其他动态数据结构(如 LinkedListArrayDeque),具体选择取决于场景需求。

4.3 空间浪费问题

ArrayList 增容时容量通常增长为原来的 2 倍,会导致未使用的空间浪费。

  • 手动调整容量

    • 在确定不再需要新增元素时,可以调用ArrayList.trimToSize()方法,将ArrayList的容量调整为当前元素的实际大小,减少空间浪费。例如:

      list.trimToSize();
      
  • 使用其他集合类(如 LinkedList

    • 如果对空间利用率要求较高,可以考虑使用 LinkedList,因为它的空间分配是动态的,不会预留多余的空间。
  • 动态调整容量增长策略

    • 如果对 ArrayList 的增容策略不满意,可以自定义一个集合类,继承自 ArrayList,并重写其扩容逻辑。例如,可以改为按固定大小增长,而不是倍增。

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

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

相关文章

FastGPT 社区版快速部署指南

产品简介 FastGPT 是基于大语言模型的智能知识库系统&#xff0c;提供以下核心能力&#xff1a; ✅ 开箱即用 - 内置数据预处理、多模型对接、权限管理 ✅ 可视化编排 - 通过 Flow 工作流实现复杂问答逻辑设计 ✅ 多场景适配 - 支持客服机器人/知识检索/数据分析等场景 &…

【css酷炫效果】纯CSS实现科技感网格背景

【css酷炫效果】纯CSS实现科技感网格背景 缘创作背景html结构css样式完整代码基础版进阶版(3D光线扫描版) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;上传后更新 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚看到csdn出活动了&#xff0c;赶时间&a…

Android BLE 权限管理

前言 android 权限一直是比较活跃的 在蓝牙权限这一块又分新版和旧版 新版权限 android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT旧版权限如9.0以下 Manifest.permission.A…

vue3:十一、主页面布局(左侧菜单折叠展开设置)

一、实现效果 二、基本实现 1、菜单容器增加展开收缩方法 在菜单容器中开启这个方法&#xff0c;值设置为一个变量 :collapseiscollapse 2、定义菜单收缩与否的变量 在js中初始化是否收缩的变量&#xff0c;初始值为不收缩(也就是展开) //左侧菜单展开与收缩 const iscolla…

Chapter 4-15. Troubleshooting Congestion in Fibre Channel Fabrics

show zone member: Shows the name of the zone to which a device belongs to. This command can be used to find the victims of a culprit device or vice versa. 显示设备所属的区域名称。该命令可用于查找罪魁祸首设备的受害者,反之亦然。 show zone active: Shows the…

使用 JDBC 插入数据并获取自动生成的主键(如 MySQL 的 AUTO_INCREMENT 或 Oracle 的序列) 的完整示例代码,包含详细注释

以下是使用 JDBC 插入数据并获取自动生成的主键&#xff08;如 MySQL 的 AUTO_INCREMENT 或 Oracle 的序列&#xff09; 的完整示例代码&#xff0c;包含详细注释&#xff1a; import java.sql.*;public class GeneratedKeysExample {// 数据库连接参数private static final St…

网络爬虫【爬虫库request】

我叫不三不四&#xff0c;很高兴见到大家&#xff0c;欢迎一起学习交流和进步 今天来讲一讲爬虫 Requests是Python的一个很实用的HTTP客户端库&#xff0c;完全满足如今网络爬虫的需求。与Urllib对比&#xff0c;Requests不仅具备Urllib的全部功能&#xff1b;在开发使用上&…

MTKAndroid12 解决SystemUI下拉框中,长按WIFI图标会导致崩溃问题

解决SystemUI下拉框中&#xff0c;长按WIFI图标会导致崩溃问题 文章目录 场景参考资料修改文件解决方案日志源码分析 总结 场景 在部分产品中偶发性发现&#xff0c; SystemUI下拉框下拉后长按WIFI图标会导致崩溃问题&#xff0c;有时候是截屏、点击Home 按键后&#xff0c;长…

第三十一篇 数据仓库(DW)与商业智能(BI)架构设计与实践指南

目录 一、DW/BI架构核心理论与选型策略1.1 主流架构模式对比&#xff08;1&#xff09;Kimball维度建模架构&#xff08;2&#xff09;Inmon企业工厂架构&#xff08;3&#xff09;混合架构 二、架构设计方法论与实施步骤2.1 维度建模实战指南&#xff08;1&#xff09;模型选择…

XSS基础靶场练习

目录 1. 准备靶场 2. PASS 1. Level 1&#xff1a;无过滤 源码&#xff1a; 2. level2&#xff1a;转HTML实体 htmlspecialchars简介&#xff1a; 源码 PASS 3. level3:转HTML深入 源码&#xff1a; PASS 4. level4:过滤<> 源码&#xff1a; PASS: 5. level5:过滤on 源码…

2025年3月AI搜索发展动态与趋势分析:从技术革新到生态重构

025年3月AI搜索发展动态与趋势分析&#xff1a;从技术革新到生态重构 一、行业动态&#xff1a;巨头布局与技术升级 谷歌推出“AI模式”&#xff0c;重新定义搜索体验 谷歌上线全新“AI模式”&#xff0c;集成多模态交互与实时数据能力&#xff0c;用户可通过文本、图片或语音…

熔断降级(Sentinel解决)

问题概述 在微服务架构中一定要预防微服务雪崩问题&#xff0c;微服务雪崩问题就是指在微服务架构中&#xff0c;当一个服务出现故障时&#xff0c;由于服务之间的依赖关系&#xff0c;故障可能会传播到其他服务&#xff0c;从而导致了大规模的服务失败&#xff0c;系统无法正…

Qt高分屏自适应

一.设置默认 DPI 感知 Windows 上的桌面应用程序可以在不同的 DPI 感知模式下运行。 这些模式可实现不同的 DPI 缩放行为,并且可以使用不同的坐标空间。 有关 DPI 感知的详细信息,请参阅在 Windows 上开发高 DPI 桌面应用程序。 请务必显式为进程设置默认 DPI 感知模式,以避…

TPCTF 2025 web 复现

文章目录 baby layoutsafe layoutSafe Layout Revengesupersqli baby layout 在index.js文件中&#xff0c;看到了有使用DOMPurify库来防止XSS操作 在package.json里可以看到版本是3.2.4,关于3.2.3是有绕过策略的。它会把script标签清除掉&#xff0c;去看bot可以看到flag是放…

Agent Team 多智能体系统解析

引言 在人工智能技术高速发展的今天&#xff0c;"多智能体协作系统"&#xff08;Agent Team&#xff09;正成为突破效率瓶颈的关键技术。与传统的单体AI不同&#xff0c;这种由多个专业化智能体组成的协同网络&#xff0c;通过分工协作和动态调整&#xff0c;展现出…

【前端 vue 或者麦克风,智能语音识别和播放功能】

前端 vue 或者麦克风&#xff0c;智能语音识别和播放功能 1. 终端安装 npm install recordrtc2.引入 import RecordRTC from recordrtc3.html&#xff08;根据自己业务更改&#xff09; <div class"Page"><el-form ref"mainFormRef" class&qu…

bootstrap 表格插件bootstrap table 的使用经验谈!

最近在开发一个物业管理软件&#xff0c;其中用到bootstrap 的模态框。同时需要获取表格数据。用传统的方法&#xff0c;本人不想用&#xff0c;考虑到bootstrap应该有获取表格数据的方法&#xff0c;结果发现要想实现获取表格数据功能&#xff0c;需要通过bootstrap的插件实现…

HTML 图像与多媒体元素:拓展学习边界的进度记录(一)

开篇&#xff1a;学习启程 在前端开发的广袤领域中&#xff0c;HTML 作为构建网页的基石&#xff0c;其重要性不言而喻。而 HTML 图像与多媒体元素&#xff0c;就像是为这座基石添上了绚丽的色彩与灵动的音符&#xff0c;赋予网页更加丰富的表现力和交互性。作为一名热衷于探索…

循环不变量原则——螺旋矩阵

题目&#xff1a;螺旋矩阵 本题相较于螺旋矩阵II的不同之处是&#xff1a;螺旋矩阵II的矩阵是n行n列的方阵&#xff0c;而本题的矩阵并不一定是方阵。所以在遵循循环不变量原则遍历完矩阵后&#xff0c;还会有一行或者一列没有遍历。 1、行多列少&#xff08;多一列没遍历&am…

【前端】Visual Studio Code安装配置教程:下载、汉化、常用组件、基本操作

文章目录 一、Visual Studio Code下载二、汉化三、常用组件1、Auto Rename Tag2、view-in-browser3、Live Server 四、基本操作五、感谢观看&#xff01; 一、Visual Studio Code下载 下载官网&#xff1a;https://code.visualstudio.com/ 进入官网后点击右上角的Download &…