【数据结构】每天五分钟,快速入门数据结构(一)——数组
目录
一.初始化语法
二.特点
三.数组中的元素默认值
四.时间复杂度
五.Java中的ArrayList类 可变长度数组
1 使用
2 注意事项
3 实现原理
4 ArrayList源码
5 ArrayList方法
一.初始化语法
// 数组动态初始化(先定义数组,指定数组长度,后续再进行赋值)
int[] arr = new int[7];
arr[0] = 1;
// 数组静态初始化(在创建数组时直接赋值)
String[] names = new String[]{"张三","李四","王五"};
int[] nums = {0,0,1,1,1,2,2,3,3,4};
//遍历数组中的元素
for( int i = 0;i < arr.length; i++){System.out.println(arr[i]);
}
二.特点
-
数组下标从0开始
-
随机访问能力:可以通过索引进行o(1)时间复杂度的访问
-
一旦初始化就不能改变长度
-
物理上和逻辑上都是连续的
三.数组中的元素默认值
int :0;
char: 空;
boolean: false;
double: 0.0;
引用类型:null
四.时间复杂度
在数组中的任意位置插入:O(n) 通过索引值访问数组元素:O(1)
查找数组中某个值所在的索引值:O(n)或者O(log n)(有序数组二分查找) 删除数组中的某个元素:O(n)
五.Java中的ArrayList类 可变长度数组
1 使用
ArrayList<String> sites = new ArrayList<String>(); // 创建一个可变长数组sites.add("张三"); // 添加元素sites.add("李四");sites.add("王五");System.out.println(sites); // 打印输出数组元素System.out.println(sites.get(1)); // 访问第二个元素sites.set(1, "柳柳"); // 修改元素内容,第一个参数为索引位置,第二个为要修改的值sites.remove(3); // 删除元素sites.size(); // 获取数组长度
2 注意事项
-
数组下标从0开始
-
数组中存储的元素类型只能为引用类型,因此需要使用基本类型的包装类
3 实现原理
自动创建一个长度为n的数组,当存放的数据量超过n时,就重新创建一个更长的数组,再将原数组内容复制到新数组中,更改数组名指向地址。
4 ArrayList源码
package java.util;public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{// 序列版本号private static final long serialVersionUID = 8683452581122892189L;// 默认容量大小private static final int DEFAULT_CAPACITY = 10;// 空数组private static final Object[] EMPTY_ELEMENTDATA = {};// 用于保存ArrayList中数据的数组private transient Object[] elementData;// ArrayList中所包含元素的个数private int size;// 带初始容量参数的构造函数public ArrayList(int initialCapacity) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);this.elementData = new Object[initialCapacity];}// 默认构造函数,其默认初始容量为10public ArrayList() {super();this.elementData = EMPTY_ELEMENTDATA;}// 带Collection参数的构造函数public ArrayList(Collection<? extends E> c) {elementData = c.toArray();size = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);}// 将此 ArrayList 实例的容量调整为列表的当前大小(实际元素个数)public void trimToSize() {modCount++;if (size < elementData.length) {elementData = Arrays.copyOf(elementData, size);}}// 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所// 指定的元素数public void ensureCapacity(int minCapacity) {int minExpand = (elementData != EMPTY_ELEMENTDATA)// any size if real element table? 0// larger than default for empty table. It's already supposed to be// at default size.: DEFAULT_CAPACITY;if (minCapacity > minExpand) {ensureExplicitCapacity(minCapacity);}}private void ensureCapacityInternal(int minCapacity) {if (elementData == EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}// 返回ArrayList中的元素个数public int size() {return size;}// 判断ArrayList是否为空public boolean isEmpty() {return size == 0;}// 判断ArrayList是否包含Object(o)public boolean contains(Object o) {return indexOf(o) >= 0;}// 返回ArrayList中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)return i;} else {for (int i = 0; i < size; i++)if (o.equals(elementData[i]))return i;}return -1;}// 返回ArrayList中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1public int lastIndexOf(Object o) {if (o == null) {for (int i = size-1; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = size-1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}// 返回此 ArrayList 实例的浅表副本public Object clone() {try {@SuppressWarnings("unchecked")ArrayList<E> v = (ArrayList<E>) super.clone();// 将当前ArrayList的全部元素拷贝到v中v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError();}}// 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组public Object[] toArray() {return Arrays.copyOf(elementData, size);}// 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)// Make a new array of a's runtime type, but my contents:return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}// 位置访问操作 @SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}// 返回ArrayList中指定位置上的元素public E get(int index) {rangeCheck(index);return elementData(index);}// 用指定的元素替代ArrayList中指定位置上的元素,并返回替代前的元素public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;}// 将指定的元素添加到ArrayList的尾部public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}// 将指定的元素插入ArrayList中的指定位置public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}// 移除ArrayList中指定位置上的元素,并返回该位置上的元素public E remove(int index) {rangeCheck(index);modCount++;E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // clear to let GC do its workreturn oldValue;}// 移除ArrayList中首次出现的指定元素(如果存在则移除并返回true,否则返回false)public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}// 私有方法,用于快速移除private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // clear to let GC do its work}// 移除ArrayList中的所有元素public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;}// 按照指定 collection 的迭代器所返回的元素顺序,// 将该 collection 中的所有元素添加到ArrayList的尾部public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountSystem.arraycopy(a, 0, elementData, size, numNew);size += numNew;return numNew != 0;}// 从指定的位置开始,将指定 collection 中的所有元素插入到ArrayList中public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountint numMoved = size - index;if (numMoved > 0)System.arraycopy(elementData, index, elementData, index + numNew,numMoved);System.arraycopy(a, 0, elementData, index, numNew);size += numNew;return numNew != 0;}// 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素protected void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = size - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// clear to let GC do its workint newSize = size - (toIndex-fromIndex);for (int i = newSize; i < size; i++) {elementData[i] = null;}size = newSize;}// 私有方法,用于范围检测private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}// 私有方法,用于add和addAllprivate void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// 移除ArrayList中Collection所包含的所有元素public boolean removeAll(Collection<?> c) {return batchRemove(c, false);}// 保留所有ArrayList和Collection共有的元素public boolean retainAll(Collection<?> c) {return batchRemove(c, true);}private boolean batchRemove(Collection<?> c, boolean complement) {final Object[] elementData = this.elementData;int r = 0, w = 0;boolean modified = false;try {for (; r < size; r++)if (c.contains(elementData[r]) == complement)elementData[w++] = elementData[r];} finally {// Preserve behavioral compatibility with AbstractCollection,// even if c.contains() throws.if (r != size) {System.arraycopy(elementData, r,elementData, w,size - r);w += size - r;}if (w != size) {// clear to let GC do its workfor (int i = w; i < size; i++)elementData[i] = null;modCount += size - w;size = w;modified = true;}}return modified;}// java.io.Serializable的写入函数// 将ArrayList的“容量,所有的元素值”都写入到输出流中private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}}// java.io.Serializable的读取函数:根据写入方式读出// 先将ArrayList的“容量”读出,然后将“所有的元素值”读出private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}}}// 返回一个从指定位置开始遍历的ListIterator迭代器public ListIterator<E> listIterator(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);return new ListItr(index);}// 返回一个ListIterator迭代器public ListIterator<E> listIterator() {return new ListItr(0);}// 返回一个Iterator迭代器public Iterator<E> iterator() {return new Itr();}// 返回一个指定范围的子List列表public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);}
}
5 ArrayList方法

相关文章:
【数据结构】每天五分钟,快速入门数据结构(一)——数组
目录 一.初始化语法 二.特点 三.数组中的元素默认值 四.时间复杂度 五.Java中的ArrayList类 可变长度数组 1 使用 2 注意事项 3 实现原理 4 ArrayList源码 5 ArrayList方法 一.初始化语法 // 数组动态初始化(先定义数组,指定数组长度…...
NBlog个人博客部署维护过程记录 -- 后端springboot + 前端vue
项目是fork的Naccl大佬NBlog项目,页面做的相当漂亮,所以选择了这个。可以参考2.3的效果图 惭愧,工作两年了也没个自己的博客系统,趁着过年时间,开始搭建一下. NBlog原项目的github链接:Naccl/NBlog: &#…...
WireShark 安装指南:详细安装步骤和使用技巧
Wireshark是一个开源的网络协议分析工具,它能够捕获和分析网络数据包,并以用户友好的方式呈现这些数据包的内容。Wireshark 被广泛应用于网络故障排查、安全审计、教育及软件开发等领域。接下将讲解Wireshark的安装与简单使用。 目录 Wireshark安装步骤…...
PyTorch detach():深入解析与实战应用
PyTorch detach():深入解析与实战应用 🌵文章目录🌵 🌳引言🌳🌳一、计算图与梯度传播🌳🌳二、detach()函数的作用🌳🌳三、detach()与requires_graddz…...
uniapp 开发一个密码管理app
密码管理app 介绍 最近发现自己的账号密码真的是太多了,各种网站,系统,公司内网的,很多站点在登陆的时候都要重新设置密码或者通过短信或者邮箱重新设置密码,真的很麻烦 所以准备开发一个app用来记录这些站好和密码…...
Postman详细攻略
🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法…...
如何在本地服务器部署TeslaMate并远程查看特斯拉汽车数据无需公网ip
文章目录 1. Docker部署TeslaMate2. 本地访问TeslaMate3. Linux安装Cpolar4. 配置TeslaMate公网地址5. 远程访问TeslaMate6. 固定TeslaMate公网地址7. 固定地址访问TeslaMate TeslaMate是一个开源软件,可以通过连接特斯拉账号,记录行驶历史,统…...
如何在CentOS安装SQL Server数据库并实现无公网ip环境远程连接
文章目录 前言1. 安装sql server2. 局域网测试连接3. 安装cpolar内网穿透4. 将sqlserver映射到公网5. 公网远程连接6.固定连接公网地址7.使用固定公网地址连接 前言 简单几步实现在Linux centos环境下安装部署sql server数据库,并结合cpolar内网穿透工具࿰…...
备战蓝桥杯 Day5
1191:流感传染 【题目描述】 有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得…...
爬虫学习笔记-scrapy爬取电影天堂(双层网址嵌套)
1.终端运行scrapy startproject movie,创建项目 2.接口查找 3.终端cd到spiders,cd scrapy_carhome/scrapy_movie/spiders,运行 scrapy genspider mv https://dy2018.com/ 4.打开mv,编写代码,爬取电影名和网址 5.用爬取的网址请求,使用meta属性传递name ,callback调用自定义的…...
Unity笔记:数据持久化的几种方式
正文 主要方法: ScriptableObjectPlayerPrefsJSONXML数据库(如Sqlite) 1. PlayerPerfs PlayerPrefs 存储的数据是全局共享的,它们存储在用户设备的本地存储中,并且可以被应用程序的所有部分访问。这意味着…...
MySQL 基础知识(八)之用户权限管理
目录 1 MySQL 权限管理概念 2 用户管理 2.1 创建用户 2.2 查看当前登录用户 2.3 修改用户名 2.4 删除用户 3 授予权限 3.1 授予用户管理员权限 3.2 授予用户数据库权限 3.3 授予用户表权限 3.4 授予用户列权限 4 查询权限 5 回收权限 1 MySQL 权限管理概念 关于 M…...
QT编写工具基本流程(自用)
以后有人让你写工具的时候,可以方便用这个模版及时提高工作效率,可以争取早点下班。包含库目录,头文件目录,输出目录以及翻译和部署,基本上都全了,也可以做收藏用用。 文章目录 1、创建项目Dialog Widget都…...
代码随想录算法训练营第三六天 | 无重叠区间、划分字母区间、合并区间
目录 无重叠区间划分字母区间合并区间 LeetCode 435. 无重叠区间 LeetCode 763.划分字母区间 LeetCode 56. 合并区间 无重叠区间 给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠…...
DP读书:《openEuler操作系统》(十)套接字 Socket 数据传输的基本模型
10min速通Socket 套接字简介数据传输基本模型1.TCP/IP模型2.UDP模型 套接字类型套接字(Socket)编程Socket 的连接1.连接概述(1)基本概念(2)连接状态(3)连接队列 2.建立连接3.关闭连接 socket 编程接口介绍数据的传输1. 阻塞与非阻塞2. I/O复用 数据的传输…...
抓住母亲节销售机会:Shopee 平台选品策略大揭秘
母亲节,作为一个重要的购物节日,为卖家带来了巨大的销售机会。在Shopee这样的电商平台上,如何通过有效的选品策略吸引消费者、提高销量呢?下面将介绍一些关键策略,帮助卖家在母亲节期间实现销售突破。 先给大家推荐一…...
Mysql如何优化数据查询方案
mysql做读写分离 读写分离是提高mysql并发的首选方案。 Mysql主从复制的原理 mysql的主从复制依赖于binlog,也就是记录mysql上的所有变化并以二进制的形式保存在磁盘上,复制的过程就是将binlog中的数据从主库传输到从库上。 主从复制过程详细分为3个阶段…...
SwiftUI 更自然地向自定义视图传递参数的“另类”方式
概览 在 SwiftUI 中,正是自定义视图让我们的 App 变得与众不同!然而,除了传统的视图接口定义方式以外,我们其实还可以有更“银杏化”的选择。 如上图所示:对于 SubView 子视图所需的参数我们一开始并没有操之过急&…...
Word第一课
文章目录 1. 文件格式1.1 如何显示文件扩展名1.2 Word文档格式的演变1.3 常见的Word文档格式 3. 文档属性理解文档属性查看文档属性 1. 文件格式 1.1 如何显示文件扩展名 文档格式指的是文件的扩展名,例如下图 对于该文件,.docx就是文件扩展名&#x…...
【Vue3】路由传参的几种方式
路由导航有两种方式,分别是:声明式导航 和 编程式导航 参数分为query参数和params参数两种 声明式导航 query参数 一、路径字符串拼接(不推荐) 1.传参 在路由路径后直接拼接?参数名:参数值 ,多组参数间使用&分隔。 <RouterLink …...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
