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

wordpress的安装/乐天seo培训

wordpress的安装,乐天seo培训,网站建设厌倦,页面制作的公司ArrayList集合底层原理ArrayList集合底层原理1.介绍2.底层实现3.构造方法3.1集合的属性4.扩容机制5.其他方法6.总结ArrayList集合底层原理 1.介绍 ​ ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在 内的所有元素。 每个 Array…

ArrayList集合底层原理

  • ArrayList集合底层原理
    • 1.介绍
    • 2.底层实现
    • 3.构造方法
    • 3.1集合的属性
    • 4.扩容机制
    • 5.其他方法
    • 6.总结

ArrayList集合底层原理

1.介绍

​ ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在 内的所有元素。 每个 ArrayList 实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造 ArrayList 时 指定其容量。

ArrayList集合特点为什么是增删慢、查询快

2.底层实现

底层使用数组实现
transient Object[] elementData;

3.构造方法

​ ArrayList 提供了三种方式的构造器,可以构造一个默认初始容量为 10 的空列表、构造 一个指定初始容量的空列表以及构造一个包含指定 collection 的元素的列表,这些元素按照 该 collection 的迭代器返回它们的顺序排列的。

// 空参构造
ArrayList<String> list1 = new ArrayList<>(); 
// 源码
public ArrayList() {/*DEFAULTCAPACITY_EMPTY_ELEMENTDATA: 指向private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};空数组.注意:默认长度是在第一次添加元素时赋值的数组*/this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}// 指定初始长度
ArrayList<String> list2 = new ArrayList<>(100);
// 源码
public ArrayList(int initialCapacity) {// 判断传入的长度大小if (initialCapacity > 0) {// 根据长度创建数组this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {// 如果等于0,返回默认长度数组// EMPTY_ELEMENTDATAprivate: 指向static final Object[] EMPTY_ELEMENTDATA = {};this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}
}
// 包含指定 collection 的元素的列表
List<String> list = new ArrayList<>();
ArrayList<String> list3 = new ArrayList<>(list);
// 源码
public ArrayList(Collection<? extends E> c) {// 先把传入的集合转成数组elementData = c.toArray();// 判断集合的长度是否等于0if ((size = elementData.length) != 0) {// 判断数组字节码类型 为什么要判断,因为c.toArray()有可能转变的不是Object数组if (elementData.getClass() != Object[].class)// copyOf把参数集合的元素拷贝到定义数组// elementData:要复制的数组// size:长度// Object[].class:要返回的新数组elementData = Arrays.copyOf(elementData, size, Object[].class);} else {//EMPTY_ELEMENTDATA:指向:private static final Object[] EMPTY_ELEMENTDATA = {};this.elementData = EMPTY_ELEMENTDATA;}
}

3.1集合的属性

//默认容量的大小
private static final int DEFAULT_CAPACITY = 10;//空数组常量
private static final Object[] EMPTY_ELEMENTDATA = {};//默认的空数组常量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//存放元素的数组,从这可以发现 ArrayList 的底层实现就是一个 Object数组
transient Object[] elementData;//数组中包含的元素个数
private int size;//数组的最大上限
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

4.扩容机制

​ 图解:
请添加图片描述

​ 扩容源码:

public boolean add(E e) {// 计数器,返回实时增加的元素个数,比如调用size()方法返回的集合元素个数modCount++;/*1.e:表示现在要添加的元素2.elementData集合底层数组名3.size本次要添加的索引位置,第一次添加size的值为0*/add(e, elementData, size);return true;
}private void add(E e, Object[] elementData, int s) {// 判断存入的位置索引if (s == elementData.length)// 调用grow方法进行扩容elementData = grow();// 索引位置小于数组长度正常存入elementData[s] = e;size = s + 1;
}private Object[] grow() {// 第一次存入元素size默认为0,进行长度加1return grow(size + 1);
}private Object[] grow(int minCapacity) {/*创建一个新的数组长度为10把原来数组元素拷贝进去minCapacity:传入的容量*/return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}private int newCapacity(int minCapacity) {// overflow-conscious code// 旧容量int oldCapacity = elementData.length;// 新容量 = 旧容量 * 1.5int newCapacity = oldCapacity + (oldCapacity >> 1);// 拿新的容量 - 传入的大小 如果结果小于0,if (newCapacity - minCapacity <= 0) {// 第一次扩容// 判断数组是否是同一个数组if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)// DEFAULT_CAPACITY默认容量=10// 比较默认容量与传入容量大小,把最大返回return Math.max(DEFAULT_CAPACITY, minCapacity);if (minCapacity < 0) // overflow 内存溢出throw new OutOfMemoryError();return minCapacity;}// 返回新的长度return (newCapacity - MAX_ARRAY_SIZE <= 0)? newCapacity: hugeCapacity(minCapacity);
}ArrayList的add方法,在插入元素之前,它会先检查是否需要扩容,然后再把元素添加到数组中最后一个元素的后面。
在 newCapacity 方法中,我们可以看见,如果当 elementData 为空数组时,它会使用默认的大小去扩容。所以说,
通过无参构造方法来创建 ArrayList 时,它的大小其实是为 0 的,只有在使用到的时候,才会通过 grow 方法去创建
一个大小为 10 的数组。第一个 add 方法的复杂度为 O(1),虽然有时候会涉及到扩容的操作,但是扩容的次数是非常
少的,所以这一部分的时间可以忽略不计。如果使用的是带指定下标的 add方法,则复杂度为 O(n),因为涉及到
对数组中元素的移动,这一操作是非常耗时的。

5.其他方法

// 修改方法
public E set(int index, E element) {// 判断是否会发生异常Objects.checkIndex(index, size);// 根据索引获取元素E oldValue = elementData(index);// 把传入的元素替换原来的元素elementData[index] = element;// 返回原来的元素return oldValue;
}// 指定索引处添加,如果当前有元素,则向右移动当前位与该位置的元素以及所有后续元素
public void add(int index, E element) {// 判断是否发生异常rangeCheckForAdd(index);// 记录修改次数, 一般研究线程安全性问题,关注这个变量modCount++;final int s;Object[] elementData;/*(s = size):数组长度,下面拷贝使用了(elementData = this.elementData):当前数组,下面有用到判断元素个数是否与数组长度相同*/if ((s = size) == (elementData = this.elementData).length)// 数组扩容前面已经讲解elementData = grow();// 将elementData中从index位置开始,长度为s-index的元素// 拷贝到从下标为index+1位置开始的新的elementData数组中// 也就是当前位于该位置的元素以及后面的元素向后移动一位System.arraycopy(elementData, index,elementData, index + 1,s - index);// 把元素赋值到指定索引处elementData[index] = element;// 长度加一size = s + 1;
}// 返回此列表中指定位置上的元素。
public E get(int index) {// 判断异常Objects.checkIndex(index, size);// 返回元素return elementData(index);
}// 移除指定索引处元素
public E remove(int index) {// 判断异常Objects.checkIndex(index, size);// 临时变量数组赋值final Object[] es = elementData;// 拿到指定索引处的元素@SuppressWarnings("unchecked") E oldValue = (E) es[index];fastRemove(es, index);return oldValue;
}
private void fastRemove(Object[] es, int i) {// 记录修改次数, 一般研究线程安全性问题,关注这个变量modCount++;// 定义临时变量final int newSize;// 判断数组长度-1,是否大于变量索引if ((newSize = size - 1) > i)/*将es中从索引i+1位置开始,长度为newSize - i的元素拷贝到从下表i + 1位置开始的新的es数组中也就是当前位于该位置的元素以及后面的元素向前一定一位*/System.arraycopy(es, i + 1, es, i, newSize - i);// 临时变量在赋值为nulles[size = newSize] = null;
}
// 移除指定元素
public boolean remove(Object o) {// 定义临时数组,并赋值final Object[] es = elementData;// 定义临时长度变量,并赋值final int size = this.size;int i = 0;// found标识,发现指定元素found: {if (o == null) {for (; i < size; i++)if (es[i] == null)break found;} else {for (; i < size; i++)if (o.equals(es[i]))break found;}return false;}// 移除元素并移动fastRemove(es, i);return true;
}

6.总结

从上述代码中可以看出,数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的 1.5 倍。这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。当我们可预知要保存的元素的多少时,要在构造 ArrayList 实例时,就指定其容量,以避免数组扩容的发生。或者根据实际需求,通过调用 ensureCapacity 方法来手动增加 ArrayList 实例的容量。

相关文章:

ArrayList集合底层原理

ArrayList集合底层原理ArrayList集合底层原理1.介绍2.底层实现3.构造方法3.1集合的属性4.扩容机制5.其他方法6.总结ArrayList集合底层原理 1.介绍 ​ ArrayList是List接口的可变数组的实现。实现了所有可选列表操作&#xff0c;并允许包括 null 在 内的所有元素。 每个 Array…...

内网部署swagger快解析映射方案发布让外网访问

计算机业内人士对于swagger并不陌生&#xff0c; 不少人选择用swagger做为API接口文档管理。Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新文件的方法&#x…...

全网最全整理,自动化测试10种场景处理(超详细)解决方案都在这......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 自动化工作流程 自动…...

【c++】指针的学习

指针是C中非常重要的概念&#xff0c;理解指针的使用可以使程序更高效&#xff0c;并且可以处理更加复杂的数据结构。 指针是一个变量&#xff0c;它存储了另一个变量的地址。通过指针访问这个变量可以提高程序的效率&#xff0c;尤其是在处理大型数据结构时。 在C中&#xff0…...

华为OD机试题,用 Java 解【水仙花数】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…...

【Linux】-- 基本指令

目录 用户管理 adduser passwd userdel pwd ls指令 -l -a -d -F -r -t -R -1 which alias ll ls -n cd cd - cd ~ touch -d stat mkdir -p rmdir rm -r -f man cp ​编辑 -r -f mv cat -n tac more less -N head tail | 管道 dat…...

JavaScript 中的 String 类型 模板字面量定义字符串

ECMAScript 6新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同&#xff0c;模板字面量保留换行字符&#xff0c;可以跨行定义字符串&#xff1a; let str1 早起的年轻人\n喜欢经常跳步;let str2 早起的年轻人喜欢经常跳步;console.log(str1);// 早起的年轻人…...

我国防疫数据报告,2022年广东花费711亿,北京人均支出第一

哈喽大家好&#xff0c;2023年已经过去一段时间了&#xff0c;随着防疫策略的调整&#xff0c;小伙伴们是不是开始到处旅行购物了呢&#xff1f;当然了&#xff0c;对于自身的健康情况小伙伴们还是要多多关注&#xff0c;不要松懈。随着春节过后有序复工复产&#xff0c;各地纷…...

OpenCV-Python学习(22)—— OpenCV 视频读取与保存处理(cv.VideoCapture、cv.VideoWriter)

1. 学习目标 学习 OpenCV 的视频的编码格式 cv.VideoWriter_fourcc&#xff1b;学会使用 OpenCV 的视频读取函数 cv.VideoCapture&#xff1b;学会使用 OpenCV 的视频保存函数 cv.VideoWriter。 2. cv.VideoWriter_fourcc()常见的编码参数 2.1 参数说明 参数说明cv.VideoWr…...

2023-03-05力扣每日一题

链接&#xff1a; https://leetcode.cn/problems/triples-with-bitwise-and-equal-to-zero/ 题意&#xff1a; 模拟一个摩天轮&#xff0c;四个舱&#xff0c;每个舱最多四人&#xff0c;给一个数组&#xff0c;表示摩天轮每切换一次座舱会来多少人排队&#xff08;人不会走…...

真正的IT技术男是什么样的?

我们经常会听到很多对IT男士的调侃称呼&#xff0c;“屌丝”、“宅男”&#xff0c;会逗的大家捧腹大笑。但是&#xff0c;大家要不要以为称呼IT男是“屌丝”、“宅男”&#xff0c;就当真以为他们是这样了。今天&#xff0c;青鸟学姐就带大家一起来了解一下&#xff0c;真正的…...

在函数中,用指针接收就可以改变相应的内容吗??

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 我们在不管指针那篇博客&#xff0c;还是在函数那篇博客中&#xff0c;我都给大家讲解过…...

Java+ElasticSearch+Pytorch实现以图搜图

以图搜图&#xff0c;涉及两大功能&#xff1a;1、提取图像特征向量。2、相似向量检索。第一个功能我通过编写pytorch模型并在java端借助djl调用实现&#xff0c;第二个功能通过elasticsearch7.6.2的dense_vector、cosineSimilarity实现。一、准备模型创建demo.py&#xff0c;输…...

【C语言学习笔记】:指针

指针的概念 指针是一个特殊的变量&#xff0c;它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容&#xff1a;指针的类型&#xff0c;指针所指向的类型&#xff0c;指针的值或者叫指针所指向的内存区&#xff0c;还有指针本身所占据的内…...

微信小程序搭建流程

一、申请微信开发者账号虽然开发微信小程序可以使用工具提供的测试号&#xff0c;但是测试号提供的功能极为有限&#xff0c;而且使用测试号开发的微信小程序不能上架发布。因此说我们想要开发一个可以上架的微信小程序&#xff0c;首先必须要申请微信开发者账号。大家尽可放心…...

嵌入式 Linux进程间的通信--信号

目录 信号 信号的概述 信号类型 信号发送 1、kill 函数 2、raise函数 3、pause函数 信号处理 可以结合上一篇文章一起看&#xff1a; 嵌入式 Linux进程之间的通信_丘比特惩罚陆的博客-CSDN博客 信号 信号的概述 软中断信号&#xff08;signal&#xff0c;又简称为…...

Vue3 核心模块源码解析(中)

【Vue3 核心模块源码解析(上)】讲到了 Vue2 与 Vue3的一些区别&#xff0c;Vue3 新特性的使用&#xff0c;以及略微带了一点源码。那么这篇文章就要从Vue3 模块源码解析 与 Vue3 执行逻辑解析这两个方面去给大家剖析 Vue3 的深层次&#xff0c;一起学习起来吧&#xff01; 这里…...

华为OD机试题 - 剩余可用字符集(JavaScript)| 含思路

华为OD机试题 最近更新的博客使用说明本篇题解:剩余可用字符集题目输入输出示例一输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全…...

焦虑的根源

归结起来&#xff0c;焦虑的原因就两条:想同时做很多事&#xff0c;又想立即看到效果。王小波说:人的一切痛苦&#xff0c;本质上都是对自己无能的愤怒。焦虑的本质也契合这一观点:自己的欲望大于能力&#xff0c;又极度缺乏耐心。焦虑就是因为欲望与能力之间差距过大。再往深了…...

1.认识网络爬虫

1.认识网络爬虫网络爬虫爬虫的合法性HTTP协议请求与响应(重点)网络爬虫 爬虫的全名叫网络爬虫&#xff0c;简称爬虫。他还有其他的名字&#xff0c;比如网络机器人&#xff0c;网络蜘蛛等等。爬虫就好像一个探测机器&#xff0c;它的基本操作就是模拟人的行为去各个网站溜达&am…...

【论文速递】WACV 2023 - 一种全卷积Transformer的医学影响分割模型

【论文速递】WACV 2023 - 一种全卷积Transformer的医学影响分割模型 【论文原文】&#xff1a;The Fully Convolutional Transformer for Medical Image Segmentation 【作者信息】&#xff1a;Athanasios Tragakis, Chaitanya Kaul,Roderick Murray-Smith,Dirk Husmeier 论…...

加密图像的脆弱水印及应用

原文题目&#xff1a;《A self-embedding secure fragile watermarking scheme with high quality recovery》 学习笔记&#xff1a; 应用场景 为了确保图像在传输过程中不被损坏&#xff0c;在将原始图像发送到云端之前&#xff0c;将用于篡改检测和恢复的水印嵌入到原始图像…...

python线上商城网站项目前台和后台源码

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;python51 获取完整源码源文件说明文档配置教程等 1、网站前台 在虚拟环境中启动程序后&#xff0c;使用浏览器访问“http://127.0.0.1:5000”即可进入网站前台首页。如图1所示。 单击首页左上角“注册”按钮&#xff0c;进…...

PowerShell 实现企业微信机器人推送消息

前言企业微信机器人 在ARMS告警管理中创建企业微信机器人后&#xff0c;您可以在通知策略中指定对应的企业微信群用于接收告警。当通知策略的匹配规则被触发时&#xff0c;系统会自动向您指定的企业微信群发送告警通知。企业微信群收到通知后&#xff0c;您可以在企业微信群中…...

IDEA集成Git就是这么简单

IDEA集成Git 文章目录IDEA集成Git配置Git环境配置Git的忽略文件①为什么需要配置忽略文件&#xff1f;②配置忽略文件③引用配置文件配置IDEA初始化项目添加到暂存区方式一&#xff1a;方式二&#xff1a;移除暂存区提交到本地库分支创建分支切换分支版本穿梭配置Git环境 配置…...

springBoot 事务基本原理

springBoot事务基本原理是基于spring的BeanPostProcessor&#xff0c;在springBoot中事务使用方式为&#xff1a; 一、在启动类上添加注解&#xff1a;EnableTransactionManagement 二、在需要事务的接口上添加注解&#xff1a;Transactional 基本原理&#xff1a; 注解&am…...

HBuilderX无线连接真机

说明 安装的是HBuilderX&#xff0c;不是HBuilder&#xff0c;adb.exe所在目录是 x:\HBuilderX\plugins\launcher\tools\adbs\ 里面可能有其他版本&#xff0c;用哪个都&#xff0c;建议使用最新的 配置 首先&#xff0c;将真机使用USB连接到电脑上。 在adb目录中启动命令…...

idea初学笔记

注:初学需安装idea专业版&#xff0c;方便学习使用idea运行内存配置从eclipse工具开发 转 idea工具开发&#xff0c;可设置idea快捷键同eclipse快捷键 file -> Settings -> Keymap -> 选择Eclipse -> OK设置idea项目整体编码格式file -> Settings -> Editor …...

C++核心编程<类和对象>(4)

C核心编程<类和对象>4.类和对象4.1封装4.1.1封装的意义封装的意义1封装的意义24.1.2struct和class区别4.1.3成员属性设置为私有4.2对象的初始化和清理4.2.1构造函数和析构函数1.1构造函数语法&#xff1a;类名(){}1.2析构函数语法&#xff1a; ~类名(){}4.2.2构造函数的分…...

编写http workshop脚本从网页缓存里解析音乐

前一篇文章 编写http workshop脚本从网站下载音乐 示范了如何使用HttpClient访问API,以及Json数据的解析; 今天我们通过解析一个网页展示如何使用内置的LibXml2的功能解析HTML,提取我们关心的内容。 这里随便搜了2个资源类的网站,竟然使用的格式是一模一样的: https://www…...