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

ArrayList集合源码解读(二)已完结

ArrayList集合源码解读(二)

前言

这篇文章已经把 ArrayList 更完了。各位还想看什么源码可以私信我~~
上节课带大家阅读了 ArrayList 中的核心扩容代码,那么今天带大家阅读下List集合中我们常用的几个方法的底层实现逻辑!

常用方法解读

笔者为大家讲解list 集合类中常用的几种操作,咱们一起看看他们的底层源码是如何实现的。

大家要区分set()add()的区别,不要弄混了。

  • int size()返回此列表中的元素数。

  • boolean isEmpty()如果此列表为空,则返回 true 。

  • boolean contains(Object o)如果此列表包含指定的元素,则返回 true 。

  • int lastIndexOf(Object o)返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回 -1。

  • E get(int index)返回此列表中指定位置的元素。

  • E set(int index, E element)用指定的元素替换此列表中指定位置的元素。

  • boolean add(E e)将指定的元素追加到此列表的末尾。

  • void add(int index, E element) 在此列表中的指定位置插入指定的元素。

  • E remove(int index)删除该列表中指定位置的元素。 将任何后续元素向左移动一位(从其索引中减去一个元素)。

源码:

// 返回此列表中的元素个数 
public int size() {return size;}// ------------------------------------// 如果集合为空,返回 truepublic boolean isEmpty() {return size == 0;}// ------------------------------------/**
* 如果此列表包含指定元素,则返回true。更正式地说,当且仅当此列表包含至少一个元素value,使得Objects. 
* equals(o,value)时,返回true
*
* @param value 要测试其是否在此列表中的元素
* @return 如果此列表包含指定元素,返回true
*/
public boolean contains(Object value) {// contains 方法底层调用的是 indexOf(Object o) 中的 indexOfRange(Object o, int s, int e)return indexOf(value) >= 0;
}// 底层方法实现
public int indexOf(Object o) {// 向下调用 indexOfRange() 方法,传入三个参数:需要查找的元素  查找起始索引  查找结束索引return indexOfRange(o, 0, size);
}// 真正实现逻辑的方法
int indexOfRange(Object o, int start, int end) {// 1.获取当前集合中的元素  (ArrayList 底层是使用 Object[] 存储元素数据的)Object[] es = elementData;// 2.如果待查找的元素 o 为 null,则从 start 起始索引开始遍历到 end 结束索引,找到第一个等于 null 的元素后返回其索引值if (o == null) {for (int i = start; i < end; i++) {if (es[i] == null) {return i;}}} else {// 3.如果待查找的元素 o 不为 null,则则从 start 起始索引开始遍历到 end 结束索引,找到第一个等于 o 的元素后返回其索引值for (int i = start; i < end; i++) {if (o.equals(es[i])) {return i;}}}// 没找到的情况,返回 -1return -1;
}// ------------------------------------// 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回 -1。
public int lastIndexOf(Object o) {// 底层调用lastIndexOfRange() 来实现,传入三个参数:待查找的元素值 o,起始索引,结束索引return lastIndexOfRange(o, 0, size);
}// 底层真正实现逻辑的方法
// 其实和上方的 indexOfRange() 方法类似,唯一变化的就是:
// indexOfRange() 是从开始索引遍历到结束索引;而 lastIndexOfRange() 是从结束索引倒序遍历。
int lastIndexOfRange(Object o, int start, int end) {Object[] es = elementData;if (o == null) {// 倒序遍历数组元素for (int i = end - 1; i >= start; i--) {if (es[i] == null) {return i;}}} else {// 倒序遍历数组元素for (int i = end - 1; i >= start; i--) {if (o.equals(es[i])) {return i;}}}return -1;
}// ------------------------------------/**
* 返回此列表中指定位置的元素。
*
* @param  index 要返回的元素的索引
* @return 此列表中指定位置的元素
* @throws IndexOutOfBoundsException 如果索引超出范围(索引<0||索引>=size())
*/
public E get(int index) {// 检查索引是否合法  如果 index < 0 || index >= size 那么抛出异常  (size 是集合中的元素个数)Objects.checkIndex(index, size);// 底层调用 elementData(int index) 方法实现return elementData(index);
}// 底层真正实现逻辑的方法
@SuppressWarnings("unchecked")  // @SuppressWarnings() 注解的作用是让编译器忽略检查,不要飘黄线
E elementData(int index) {// 直接返回当前索引对应的元素return (E) elementData[index];
}// ------------------------------------/**
* 将此列表中指定位置的元素替换为指定元素。
*
* @param index 要替换的元素的索引
* @param element 要存储在指定位置的元素
* @return 先前位于指定位置的元素
* @throws IndexOutOfBoundsException 如果索引超出范围(索引<0||索引>=size())
*/public E set(int index, E element) {// 检查索引是否合法  如果 index < 0 || index >= size 那么抛出异常  (size 是集合中的元素个数)Objects.checkIndex(index, size);// 获取指定索引的元素,上面有调用,此次不重复讲解// 因为要返回原先处于该位置的元素,所以需要先用个变量保存E oldValue = elementData(index);// 替换掉旧元素elementData[index] = element;return oldValue;}// ------------------------------------/**
* 在此列表中的指定位置插入指定的元素。
* 先调用 rangeCheckForAdd 对index进行界限检查;然后调用 grow 方法保证 capacity  足够大;
* 再将从index开始之后的所有成员后移一个位置;将element插入index位置;最后size加1。
*/public void add(int index, E element) {// 检查索引是否合法 rangeCheckForAdd(index);// 版本号 +1// 此列表在结构上被修改的次数。结构修改是指改变列表大小的修改,或者以其他方式扰乱列表,使得正在进行的迭代可能会产生不正确的结果。modCount++;final int s;Object[] elementData;// 这句话的意思是 首先将 size 的值赋值给局部变量 s,再将数组底层存储数据的 Object[] elementData  赋值给局部变量 elementData。最好判断他们的长度是否一样if ((s = size) == (elementData = this.elementData).length) {// 扩容的核心方法 grow()  上面有讲,此处不再过多陈述elementData = grow();}// System.arraycopy() 数组拷贝方法很重要!!// 第一个参数是要复制的数组 a1// 第二个参数是从a1的哪个索引开始赋值// 第三个参数是要复制到哪个数组 a2// 第四个参数是从 a2 这个数组的哪个索引开始覆盖// 第五个参数是指复制多少个元素System.arraycopy(elementData, index,elementData, index + 1,s - index);elementData[index] = element;size = s + 1;}// 判断索引是否符合规则  
// 和上方的 Objects.checkIndex() 方法的区别在于:
// rangeCheckForAdd() 方法判断的区间是 index < 0 || index > size
// checkIndex() 方法判断的区间是 index < 0 || index >= sizeprivate void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}

相关文章:

ArrayList集合源码解读(二)已完结

ArrayList集合源码解读&#xff08;二&#xff09; 前言 这篇文章已经把 ArrayList 更完了。各位还想看什么源码可以私信我~~ 上节课带大家阅读了 ArrayList 中的核心扩容代码&#xff0c;那么今天带大家阅读下List集合中我们常用的几个方法的底层实现逻辑&#xff01; 常用…...

光伏逆变器、MPPT、PCS储能变流器、BMU、BCU、BDU和液冷机组

一、光伏逆变器 光伏逆变器&#xff08;PV inverter或solar inverter&#xff09;可以将光伏&#xff08;PV&#xff09;太阳能板产生的可变直流电压转换为市电频率交流电&#xff08;AC&#xff09;的逆变器&#xff0c;可以反馈回商用输电系统&#xff0c;或是供离网的电网使…...

OpenHarmony编译

简介&#xff1a;本文将会介绍编译OpendHarmony环境的搭建、编译、和刷机&#xff08;rk3568&#xff09; 使用场景&#xff1a;修改系统源码&#xff0c;需要验证修改的功能是否正确、编译镜像、编译SDK 1、VS Code&#xff0c;下载链接&#xff0c;用于修改源码 2、linux环…...

C语言典型例题30

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.7 从银行贷了一笔款d&#xff0c;准备每月还款额为p&#xff0c;月利率为r&#xff0c;计算多少个月能还清。 设d30000元&#xff0c;p6000元&#xff0c;r1%。对求得的月份取小数点后一位&#xff0c;对第二…...

springMVC @RestControllerAdvice注解使用方式

使用 RestControllerAdvice 的主要场景包括&#xff1a; 全局异常处理&#xff1a;处理所有控制器中抛出的未捕获异常。数据校验失败处理&#xff1a;处理 Bean Validation 校验失败的情况。自定义响应&#xff1a;统一定义响应格式或错误信息。 RestControllerAdvice 注解的…...

HarmonyOS鸿蒙开发岗位面试中关于组件的问题总结

文章目录 1. 鸿蒙组件的基本概念2. 组件的使用3. 布局管理4. 组件间通信5. 组件化开发6. 性能优化7. 实战应用 鸿蒙应用开发岗位面试中关于鸿蒙组件的问题&#xff0c;通常会涉及多个关键知识点&#xff0c;这些知识点涵盖了鸿蒙组件的基本概念、使用、布局管理、性能优化、组件…...

Unity 在Editor下保存对Text组件的文本的修改

Unity 在Editor下保存对Text组件的文本的修改 /****************************************************文件&#xff1a;TimeStampForText.cs作者&#xff1a;lenovo邮箱: 日期&#xff1a;2024/8/8 1:9:21功能&#xff1a; *************************************************…...

mysql 日志爆满,删除日志文件,定时清理日志

今天发现网站不能正常访问&#xff0c;于是登陆服务器查找问题。 机智的我随手用命令&#xff1a;df -l 发现 硬盘爆满了&#xff0c;于是就知道问题所在了。 Filesystem 1K-blocks Used Available Use% Mounted on/dev/xvda1 20641404 16963004 16929876 10…...

MySQL学习(19):锁

1.什么是锁 锁是计算机协调多个进程或线程并发访问某一资源的机制。 在数据库中&#xff0c;数据是供许多用户共享的资源&#xff0c;数据库必须保证数据并发访问的一致性、有效性&#xff0c;这就要靠锁来协调实现。 MySOL中的锁&#xff0c;分为以下三类&#xff1a; &am…...

【出海日记】关于 KD ,数据工具的陷阱

一个关键词&#xff1a;deepwoken builder 对标的竞品&#xff1a;deepwoken.co 初步分析&#xff1a; https://ahrefs.com/keyword-difficulty/?countryus 显示这个关键词优化难度极低 拿流量的是一个内页&#xff0c;单靠这个内页一个月有 22 万的流量 看起来很香&#x…...

【k8s集群部署篇】在openEuler环境下部署多master高可用kubernetes集群详细教程(V1.30版本)

【k8s集群部署篇】在openEuler环境下部署多master高可用kubernetes集群详细教程(V1.30版本) 一、相关名词介绍1.1 k8s简介1.2 Keepalived简介1.3 HAProxy简介二、本次实践介绍2.1 环境规划介绍2.2 本次实践简介三、所有节点基础环境配置3.1 主机配置工作3.2 关闭防火墙和seli…...

数据结构:链表经典算法OJ题

目录 前言 一、移除链表元素 二、反转链表 三、合并两个有序链表 四、链表的中间节点 五、环形链表的约瑟夫问题 前言 在了解了链表的相关知识后&#xff0c;我们还需要一些题目进行练习加深对链表这方面知识的理解&#xff0c;也可以用来检测链表这块学的的怎么样&#…...

【线性代数】【二】2.2 极大线性无关组与向量空间的基

文章目录 前言一、极大线性无关组二、向量空间的基三、向量维数与向量空间维数总结 前言 上一篇中我们介绍了向量空间的概念&#xff0c;并且学习了对任意给出的一组向量&#xff0c;如果构造一个向量空间。本文将更加细致的去分析张成一个向量空间&#xff0c;具有哪些性质。…...

OD C卷 - CPU算力分配

CPU算力分配 两组服务器A、B, 每组有多个算力不同的CPU&#xff1b;为了让两组服务器的算力和相等&#xff0c;允许两组各选出一个CPU进行一次交换&#xff1b;求两组中用于交换的CPU算力&#xff0c;从A中选出的算力尽可能小&#xff1b; 输入描述&#xff1a; 第一行 输入L…...

matlab实现红绿灯识别

在MATLAB中实现红绿灯识别通常涉及图像处理技术&#xff0c;包括颜色分割、形态学操作、边缘检测等步骤。下面我将给出一个基本的框架和示例代码&#xff0c;用于在MATLAB中识别图像中的红绿灯。 步骤 1: 读取图像 首先&#xff0c;你需要有一张包含红绿灯的图像。 img imr…...

base64 转 pdf

工作中经常会遇到一些签名的pdf传输&#xff0c;一般都是base64编码&#xff0c;这样就需要我们手动转为pdf&#xff0c; 其实根本不需要自己使用pdf的库写入&#xff0c;只是数据的简单写入就行 package mainimport ("encoding/base64""fmt""os&quo…...

vue2项目微信小程序的tabs切换效果

在 Vue 2 项目中实现类似微信小程序的 tabs 切换效果&#xff0c;可以通过 Vue 的 router-view 和 <router-link> 来完成。这里我们使用 Vue Router 来创建一个标签页切换的效果。 步骤 1: 安装 Vue Router 如果还没有安装 Vue Router&#xff0c;首先需要安装它&#…...

WPF动画的使用

前言 弹幕是什么&#xff1f;这里是使用动画将控件弹起来&#xff0c;通过C#提供的多样化动画类型&#xff0c;我们可以制做出丰富的界面效果。主要有基于时间的动画和基于属性的动画。 1、Animatable 一个提供动画支持的抽象类。 继承 Object DispatcherObject Depende…...

跑腿代购app系统源码开发及功能分析

随着互联网技术的飞速发展和人们生活节奏的加快&#xff0c;跑腿代购服务作为一种便捷的生活方式&#xff0c;正逐渐渗透到我们日常生活的方方面面。从日常购物、餐饮外卖到文件传递、药品代购&#xff0c;跑腿服务以其高效、灵活的特点赢得了广大用户的青睐。而支撑这一服务高…...

mysql数据库:字符串函数

mysql数据库&#xff1a;字符串函数 mysql数据库&#xff1a;字符串函数 concat(str1,str2,…strn) 连接str1&#xff0c;str2&#xff0c;…&#xff0c;strn为一个字符串 select concat(abc,def)replace(str,a,b) 用字符串b替换str中所有出现的字符串a insert(str,x,y,instr…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...