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

集合与容器:List、HashMap(II)

一、ArrayList

是集合框架中最核心的动态数组实现,高频使用的容器之一。

1. 核心数据结构

基于数组实现,维护elementData数组存储元素:

transient修饰的elementData不会被默认序列化(通过自定义序列化逻辑优化存储)

2. 动态扩容机制

当添加元素时发现容量不足,触发 grow(int minCapacity) 扩容:

核心逻辑:

  • 扩容倍率:新容量 = 旧容量 * 1.5 (位运算 oldCapacity >> 1 代替除法优化性能)
  • 数组拷贝:Arrays.copyOf() 底层使用System.arraycopy(),为本地方法(效率高)

3. 添加元素流程

以add(E e)为例:

  • 容量检查:若当前数组已满,触发扩容后再插入
  • 尾部插入:时间复杂度O(1)

arrayList.add(a):

场景1:第一次添加元素(空数组扩容)

触发条件:默认构造的ArrayList首次调用add()。(初始elementData为空数组)

流程:

  1. minCapacity = size + 1 = 1
  2. 判断当前容量 elementData.length = 0,需要扩容
  3. 计算新容量 newCapacity = max(10, 1) = 10
  4. 新数组elementData = new Object[10], 将元素插入首位。

场景2:末尾插入且容量充足

  1. ensureCapacityInternal(size + 1)  -->  无需扩容
  2. elementData[size++] = e  -->  直接插入末尾,无需移动元素,O(1)时间复杂度

场景3:触发扩容(容量不足)

例:数组已满(size == elementData.length)时添加新元素。

扩容步骤:

  1. oldCapacity = 10;
  2. 计算增长量 oldCapacity >> 1 = 5  -->  newCapacity = 15;
  3. Arrays.copyOf(elementData, 15) -->  快速本地方法拷贝数组;
  4. 扩容代价:数组拷贝O(n),需要在插入时尽量避免频繁扩容;

安全检查方法:hugeCapacity(minCapacity)

 hugeCapacity的决策逻辑分为:

case1:minCapacity 正常(非负 且 <=MAX_ARRAY_SIZE)

  • 返回 MAX_ARRAY_SIZE (即Integer.MAX_VALUE - 8)。

case2:minCapacity > MAX_ARRAY_SIZE

  • 直接返回Integer.MAX_VALUE(允许尝试分配更大的容量,但可能导致OOM)。

异常处理:minCapacity < 0(溢出导致)

  • 抛出OutOfMemoryError (申请容量已超过Integer.MAX_VALUE,无法满足)

场景4:中间插入(需移动元素-add(int index, E e))

例如:list.add(2, "hello"); // 在索引2处插入元素

流程:

  1. 检查索引合法性(index >= 0 && index <= size)
  2. 检查容量 --> 不够则扩容
  3. 计算需要移动的元素数量:numMoved = size - index = 3.
  4. 调用System.arraycopy(elementData, 2, elememtData, 3, numMoved),将原数据从索引2开始的元素后移1位。
  5. elementData[2] = "hello".
  6. 时间复杂度:平均O(n)

核心方法:

4. 删除元素流程

核心点:

  • 移动代价:平均时间复杂度O(n),末尾删除为O(1)
  • GC处理:手动赋值null避免内存泄漏

5. modCount作用

迭代器通过modCount追踪结构性修改:

结构性修改:

  • 任何导致size变化或元素位置变化的操作(增、删、排序等)
  • 多线程问题:未同步时快速失败机制能检测部分并发问题

6. 线程安全性

非线程安全:ArrayList的设计不保证多线程环境下的安全

替代方案:

  • Collections.synchronizedList(new ArrayList<>()) 同步包装类
  • CopyOnWriteArrayList写时复制容器(适合读多写少场景)

7. 性能优化技巧

(1)初始化时指定容量

ArrayList<String> list = new ArrayList<>(1000);  // 直接指定初始容量

(2)批量操作优先:避免循环内多次扩容

list.addAll(Arrays.asList("A","B","C"));   // 批量添加减少扩容次数

(3)谨慎使用contains/remove(Object):时间复杂度O(n),高频操作可改用HashSet

二、LinkedList

是一个基于双向链表实现的集合类,经常被拿来和ArrayList做比较。

LinkedList仅仅在头尾插入或者删除元素的时候时间复杂度近似O(1),其他情况增删元素的平均时间复杂度都是O(n)。

LinkedList 中的元素是通过Node定义的:

1. 初始化

LinkedList中有一个无参构造函数和一个有参构造函数。

2. 获取元素

LinkedList获取元素相关的方法有三个:

(1)getFirst()

(2)getLast()

(3)get(int index)

核心在于node(int index)方法:

get(int index) 和 remove(int index) 等方法内部都调用了该方法来获取对应的节点。

该方法通过比较索引值与链表size的一半大小来确定从链表头还是尾开始遍历。如果索引值小于size的一半,就从链表头开始遍历,反之从链表尾开始遍历。这样可以在较短的时间内找到目标节点,充分利用了双向链表的特性来提高效率。

3. 插入元素

add() 方法有两个版本:

  • add(E e):用于在LinkedList的尾部插入元素,即将新元素作为链表的最后一个元素,时间复杂度为O(1)。
  • add(int index, E element):用于在指定位置插入元素,这种插入方式需要先移动到指定位置,再修改指定节点的指针完成插入/删除,因此需要移动平均n/4个元素,时间复杂度为O(n)。

4. 删除元素

三、HashMap

1. 二叉搜索树

针对有序数组的存储,查找(二分查找)的效率可以达到O(log2n),但是插入和删除操作因为需要挪动后面所有的元素,所以时间复杂度是O(n)。由此引入二叉搜索树,即BST树。

左 < 根 < 右,中序遍历:从小到大。

详见:数据结构与算法 Java_java数据结构与算-CSDN博客

6.4的(3)二叉排序树 和(4)平衡二叉树

不选择二叉搜索树的原因:

2. 红黑树

红黑树的特点:

① 是二叉搜索树(左 < 根 < 右)——根左右

② 根和叶子(null)节点都是黑色——根叶黑

③ 不存在连续的两个红色节点——不红红

④ 任一节点到叶的所有路径黑节点数量相同——黑路同



3. HashMap

相关文章:

集合与容器:List、HashMap(II)

一、ArrayList 是集合框架中最核心的动态数组实现&#xff0c;高频使用的容器之一。 1. 核心数据结构 基于数组实现&#xff0c;维护elementData数组存储元素&#xff1a; transient修饰的elementData不会被默认序列化&#xff08;通过自定义序列化逻辑优化存储&#xff09;…...

Eclipse 视图(View)

Eclipse 视图(View) Eclipse 视图(View)是 Eclipse 界面的重要组成部分,它提供了用户交互的平台,使得用户可以通过图形界面来编辑、调试、分析代码等。在本文中,我们将深入探讨 Eclipse 视图的功能、使用方法以及它们在软件开发中的作用。 1. 视图的功能 Eclipse 视图具…...

《AI大模型应知应会100篇》第3篇:大模型的能力边界:它能做什么,不能做什么

第3篇&#xff1a;大模型的能力边界&#xff1a;它能做什么&#xff0c;不能做什么 摘要 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;已经成为许多领域的核心技术。然而&#xff0c;尽管它们展现出了惊人的能力&#xff0c;但也有明显的局限性…...

Springboot----@Role注解的作用

Role(BeanDefinition.ROLE_INFRASTRUCTURE) 是 Spring 框架中的一个注解&#xff0c;用于显式标记 Bean 的角色&#xff0c;表明该 Bean 是 Spring 容器内部的基础设施组件&#xff08;如后置处理器、工具类等&#xff09;&#xff0c;而非用户直接使用的业务 Bean。其核心作用…...

小程序API —— 58 自定义组件 - 创建 - 注册 - 使用组件

目录 1. 基本介绍2. 全局组件3. 页面组件 1. 基本介绍 小程序目前已经支持组件化开发&#xff0c;可以将页面中的功能模块抽取成自定义组件&#xff0c;以便在不同的页面中重复使用&#xff1b;也可以将复杂的页面拆分成多个低耦合的模块&#xff0c;有助于代码维护&#xff1…...

前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标节流处理、throttle、限制触发频率(setTimeout、clearInterval)

文章目录 使用lodashjs库手动实现节流&#xff08;通过判断之前设定的定时器setTimeout是否存在&#xff09; 使用lodashjs库 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…...

在 Android Studio 中运行安卓应用到 MuMu 模拟器

一、准备工作 1、​​确保 MuMu 模拟器已正确安装并启动​​ 从官网下载安装最新版 MuMu 模拟器。启动后&#xff0c;建议在设置中调整性能参数&#xff08;如 CPU 核心数和内存分配&#xff09;&#xff0c;以保证流畅运行。 2、​​配置 Android Studio 环境​&#xff08;按…...

从文本到多模态:如何将RAG扩展为支持图像+文本检索的增强生成系统?

目录 从文本到多模态&#xff1a;如何将RAG扩展为支持图像文本检索的增强生成系统&#xff1f; 一、为什么需要扩展到多模态&#xff1f; 二、多模态 RAG 系统的基本架构 三、关键技术点详解 &#xff08;一&#xff09;多模态嵌入&#xff08;Embedding&#xff09;技术 …...

【JavaEE】网络原理详解

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…...

Python项目-基于Flask的个人博客系统设计与实现(2)

源代码 续 {% extends base.html %}{% block title %}评论管理{% endblock %}{% block content %} <div class"container py-4"><div class"row"><div class"col-md-3"><div class"list-group mb-4"><a h…...

洛谷题单3-P1720 月落乌啼算钱(斐波那契数列)-python-流程图重构

题目描述 给定一个整数 N N N&#xff0c;请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式&#xff0c;即除非给定的原数为零&#xff0c;否则反转后得到的新数的最高位数字不应为零&#xff08;参见样例 2&#xff09;。 输入格式 一个整数 N N N。 …...

NOIP2013提高组.华容道

题目 509. 华容道 算法标签: 搜索, b f s bfs bfs, s p f a spfa spfa 思路 不难发现, 在人移动的过程中, 箱子是不动的, 从当前位置到下一个箱子旁边的位置不会移动箱子, 可以预处理出人在每个位置到其他位置的距离预处理, 从某一个状态出发, 走到另一个状态的最短路使…...

政安晨【超级AI工作流】—— 基于COZE探索有趣的主题互动问答工作流(同宇宙儿童提问机)

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本例&#xff0c;我们将从零展示如何创建一款专门针对儿童对某项主题进行问答的对话流智能体…...

Derivatives and Differentiation (导数和微分)

Derivatives and Differentiation {导数和微分} 1. Derivatives and Differentiation (导数和微分)1.1. Visualization Utilities 2. Chain Rule (链式法则)3. DiscussionReferences For a long time, how to calculate the area of a circle remained a mystery. Then, in Anc…...

P17_ResNeXt-50

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、模型结构 ResNeXt-50由多个残差块&#xff08;Residual Block&#xff09;组成&#xff0c;每个残差块包含三个卷积层。以下是模型的主要结构&#xff1…...

Ubuntu上离线安装ELK(Elasticsearch、Logstash、Kibana)

在 Ubuntu 上离线安装 ELK(Elasticsearch、Logstash、Kibana)的完整步骤如下: 一.安装验证 二.安装步骤 1. 在联网机器上准备离线包 (1) 安装依赖工具 #联网机器 sudo apt update sudo apt install apt-rdepends wget(2) 下载 ELK 的 .deb 安装包 #创建目录将安装包下载…...

PyCharm 下载与安装教程:从零开始搭建你的 Python 开发环境

PyCharm 是一款专为 Python 开发设计的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了强大的代码编辑、调试、版本控制等功能&#xff0c;是 Python 开发者的必备工具之一。如果你是初学者&#xff0c;或者正在寻找一款高效的开发工具&#xff0c;这篇文章将帮助…...

TSMaster在新能源汽车研发测试中的硬核应用指南

——从仿真到标定&#xff0c;全面赋能智能汽车开发 引言&#xff1a;新能源汽车测试的挑战与TSMaster的破局之道 新能源汽车的快速发展对研发测试提出了更高要求&#xff1a;复杂的电控系统、高实时性通信需求、多域融合的验证场景&#xff0c;以及快速迭代的开发周期。传统测…...

C/C++的条件编译

一、什么是条件编译&#xff1f; 条件编译是指在编译阶段根据某些条件来决定是否编译某段代码。这通常通过预处理指令来实现&#xff0c;比如 #if、#ifdef、#ifndef、#else、#elif 和 #endif。 二、为什么使用条件编译&#xff1f; ​​跨平台开发​​&#xff1a;不同的操作…...

使用 requests 和 BeautifulSoup 解析淘宝商品

以下将详细解释如何通过这两个库来实现按关键字搜索并解析淘宝商品信息。 一、准备工作 1. 安装必要的库 在开始之前&#xff0c;确保已经安装了 requests 和 BeautifulSoup 库。如果尚未安装&#xff0c;可以通过以下命令进行安装&#xff1a; bash pip install requests…...

安装 TabbyAPI+Exllamav2 和 vLLM 的详细步骤

在 5090 显卡上成功安装 TabbyAPIExllamav2 和 vLLM 并非易事&#xff0c;经过一番摸索&#xff0c;我总结了以下详细步骤&#xff0c;希望能帮助大家少走弯路。 重要提示&#xff1a; 用户提供的 PyTorch 安装使用了 cu128&#xff0c;这并非标准 CUDA 版本。请根据你的系统实…...

小动物多导生理记录仪产品需求定义

小动物多导生理记录仪的产品需求定义如下&#xff1a; 功能需求 信号采集功能&#xff1a;能采集多种生理信号&#xff0c;如心电、脑电、肌电、眼电、胃肠电、诱发电位、神经电位、细胞电位、有创血压、无创血压、dP/dt、体温、肌张力、呼吸波、呼吸流速、组织血流速度、血管…...

深入理解C++引用:从基础到现代编程实践

一、引用的本质与基本特性 1.1 引用定义 引用是为现有变量创建的别名&#xff0c;通过&符号声明。其核心特点&#xff1a; 必须初始化且不能重新绑定 与被引用变量共享内存地址 无独立存储空间&#xff08;编译器实现&#xff09; 类型必须严格匹配 int value 42; in…...

黑白彩色相机成像原理

文章目录 黑白相机成像原理彩色相机成像原理 黑白相机成像原理 参考&#xff1a;B站优致谱视觉 光线聚焦&#xff1a;相机镜头将外界景物反射的光线聚焦到相机内部的成像平面上。光电转换&#xff1a;成像平面上通常是图像传感器&#xff0c;黑白相机常用的是CCD&#xff08…...

室内指路机器人是否支持环境监测功能?

并非所有室内指路机器人都具备环境监测功能。那些支持环境监测的室内指路机器人&#xff0c;往往在设计上进行了针对性的优化&#xff0c;搭载了一系列先进且实用的传感器。温湿度传感器犹如一位敏锐的 “温度湿度侦探”&#xff0c;时刻精准地监测室内温度与湿度&#xff0c;为…...

去中心化自治组织(DAO):革新未来治理的下一站

去中心化自治组织(DAO):革新未来治理的下一站 引言 去中心化自治组织(DAO)的诞生,像是互联网时代的一道新曙光。它打破了传统组织的等级壁垒,以去中心化和智能合约为核心,让社区成员能够直接参与决策并共享收益。从NFT社区到投资基金,DAO的应用场景正以前所未有的速…...

Docker安装、配置Mysql5.7

1.创建必要的目录 # 创建目录 mkdir -p ~/docker/software/mysql/{conf,log,data} 2.如果没有docker-compose.yml文件的话&#xff0c;先创建docker-compose.yml 配置文件一般长这个样子 version: 3services:mysql:image: mysql:5.7.36container_name: mysqlports:- "…...

#管理Node.js的多个版本

在 Windows 11 上管理 Node.js 的多个版本&#xff0c;最方便的方法是使用 nvm-windows&#xff08;Node Version Manager for Windows&#xff09;。它允许你轻松安装、切换和管理多个 Node.js 版本。 &#x1f4cc; 方法 1&#xff1a;使用 nvm-windows&#xff08;推荐 ✅&a…...

基于DrissionPage的Taptap热门游戏数据爬虫实战:从Requests到现代爬虫框架的迁移指南(含完整代码复制)

目录 ​编辑 一、项目重构背景与技术选型 1.1 原代码问题分析 1.2 DrissionPage框架优势 二、环境配置与基础改造 2.1 依赖库安装 2.2 基础类改造 三、核心功能模块重构 3.1 请求参数自动化生成 3.2 智能页面渲染 3.3 数据解析优化 四、数据库操作增强 4.1 批量插入…...

Online Sparse Reconstruction for Scanning Radar Using Beam-Updating q-SPICE论文阅读

Online Sparse Reconstruction for Scanning Radar Using Beam-Updating q -SPICE 论文概述关键技术与创新点实验结果学术术语解释1. 论文的研究目标与实际问题2. 论文提出的新方法、模型与公式2.1 核心方法:Beam-Updating q-SPICE2.1.1 循环最小化(Cyclic Minimization)2.1…...