Java List 扩容机制探究(ArrayList 、Vector、LinkedList)

news/2024/5/19 5:27:36/文章来源:https://blog.csdn.net/weixin_45525272/article/details/127353239

文章目录

  • List扩容
    • ArrayList 扩容机制
      • 结论:无参构造创建的ArrayList的初始空间为0,在添加第一个元素的时候空间会默认为10,之后扩容会为当前容量的1.5倍。
      • 0->10->15->22->33->49
      • 源码分析
        • 1.ArrayList list = new ArrayList();
        • 2. list.add(1);
    • Vector 扩容机制
      • 结论:无参构造默认空间为10,每次扩大一倍。
      • 源码分析
    • LinkedList 扩容机制
      • 结论:LinkedList是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。
  • 其他问题
    • 扩容后的size是多少?还是实际元素大小
    • 给了初始值,它会给我自动扩充为10、15、22......吗?不会

List扩容

ArrayList 扩容机制

结论:无参构造创建的ArrayList的初始空间为0,在添加第一个元素的时候空间会默认为10,之后扩容会为当前容量的1.5倍。

0->10->15->22->33->49

演示代码

public static void main(String[] args) {ArrayList list = new ArrayList();for (int i = 0; i <= 9; i++) {list.add(i);}list.add(10);list.add(11);list.add(12);
}

第一次调试截图:此时ArrayList内未添加任何元素,默认为0;

img

第二次调试截图:当向ArrayList中添加第一个元素的时候,空间变为10。

img

10条插入完后,再插入就会变成15

img

这是第二次扩容为,扩容为15

再继续插入16个,扩容为22

img

第三次扩容22

源码分析

1.ArrayList list = new ArrayList();

会调用无参构造器,新建一个ArrayList。将elementData设置为DEFAULTCAPACITY_EMPTY_ELEMENTDATA

   /*** Constructs an empty list with an initial capacity of ten.*/public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}

通过源码,我们知道DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的数组。

  /*** Shared empty array instance used for default sized empty instances. We* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when* first element is added.*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

2. list.add(1);

将1进行Integer包装

   public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}

通过add类进行元素添加

/*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}

通过ensureCapacityInternal方法来确保容量足够,此处的Math.max(DEFAULT_CAPACITY, minCapacity);就是确保第一次扩容空间为10

   private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}

ensureCapacityInternal方法会调用ensureExplicitCapacity方法来确保空间,modCount用来多线程的判断,此处不赘述

   private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}

ensureExplicitCapacity方法会调用grow方法,扩容1.5倍,就是在此发生的。 int newCapacity = oldCapacity + (oldCapacity >> 1);

/*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/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);}

Vector 扩容机制

结论:无参构造默认空间为10,每次扩大一倍。

如下代码

public class ArrayExercise {public static void main(String[] args) {Vector vector = new Vector();for (int i = 0; i < 10; i++) {vector.add(i);}vector.add(10);vector.add(11);vector.add(12);}
}

调试过程略。

源码分析

初始化会默认调用无参,再调用有参数构造器,空间默认10。

   /*** Constructs an empty vector so that its internal data array* has size {@code 10} and its standard capacity increment is* zero.*/public Vector() {this(10);}

扩容的主要操作在grow中的int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);方法,capacityIncrement默认是0,所以等价newCapacity=oldCapacity+oldCapacity

   /*** Appends the specified element to the end of this Vector.** @param e element to be appended to this Vector* @return {@code true} (as specified by {@link Collection#add})* @since 1.2*/public synchronized boolean add(E e) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = e;return true;}private void ensureCapacityHelper(int minCapacity) {// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);elementData = Arrays.copyOf(elementData, newCapacity);}

LinkedList 扩容机制

结论:LinkedList是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。

其他问题

扩容后的size是多少?还是实际元素大小

调试下我们可以发现,虽然elementData进行了扩容,但是实际大小还是元素的个数,别被唬住了

在这里插入图片描述

给了初始值,它会给我自动扩充为10、15、22…吗?不会

别激动,给多少就是多少
别激动

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

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

相关文章

Android多媒体架构

Android多媒体架构 要实现我们的媒体播放器 主要使用的就是android media MediaPlayer 这样的一个类 来为我们的播放器的实现提供一个主要功能 而这个类的实现又依赖于 JNI层的 1)一些接口 2)Libmedia.so 库 (这个库才是 mediaplayer类的真正实现) 再往下就是我们的se…

产品能力|书山有路-趣味算法(第二版)读书笔记part1

系列文章目录 趣味算法&#xff08;第二版&#xff09;读书笔记&#xff1a; day1: 序章|学习的方法和目标. day2:算法之美|打开算法之门与算法复杂性 day3.算法之美|函数特性与图形 day4.数学之美|斐波那契数列 后续补充完善 提示&#xff1a;写完文章后&#xff0c;目录可以…

Kubernetes_16_静态Pod网关apiserver的audit审计日志

系列文章目录 文章目录系列文章目录前言一、理论&#xff1a;kube-apiserver的审计日志1.1 kube-apiserver.yaml 文件的五行修改1.2 audit-policy.yaml文件的修改二、实践&#xff1a;编写策略文件&#xff0c;打印想要的审计日志2.1 步骤1&#xff1a;编写修改policy.yaml文件…

05_排序与分页

1.排序数据 1.1排序规则 如果没有使用排序操作&#xff0c;默认情况下查询返回的数据是按照添加数据的顺序显示的。 使用ORDER BY子句排序 ASC (ascend):升序 DESC (descend):降序 ORDER BY子句在SELECT语句的结尾。 1.2单列排序 1.简单使用排序 #如果没有使用排序操作&am…

每日算法、面试题

目录 2022/10/16 一、算法 翻转字符串里的单词 找出字符串中第一个匹配项的下标 二、面试题 SpringMvc中如何解决POST请求的中文乱码问题 SpringMvc的工作流程 2022/10/16 一、算法 翻转字符串里的单词 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 …

【Nginx】三、Nginx实现四层负载均衡Nginx实现限流防盗链流量镜像

Nginx实现四层负载均衡一、Nginx实现四层负载均衡1、四层负载均衡与七层负载均衡区别2、Nginx四层负载均衡配置3、SocketTool工具4、TCP&UDPDebug工具二、Nginx实现限流三、Nginx实现防盗链四、Nginx流量镜像一、Nginx实现四层负载均衡 我们之前介绍的HTTP负载均衡&#x…

Silane-PEG-Alkyne,硅烷-聚乙二醇-炔基用于修饰蛋白类

An English name&#xff1a;Silane-PEG-Alkyne Chinese name&#xff1a;硅烷-聚乙二醇-炔基 Item no&#xff1a;X-GF-0314-10k CAS&#xff1a;N/A Formula&#xff1a;N/A MW&#xff1a;Silane-PEG-Alkyne5000、Silane-PEG-Alkyne3400、Silane-PEG-Alkyne2000、硅烷-…

【附源码】计算机毕业设计SSM美食菜谱网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

(附源码)计算机毕业设计SSM基于JAVA线上订餐系统

&#xff08;附源码&#xff09;计算机毕业设计SSM基于JAVA线上订餐系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

【Vue Router】

资料 官网&#xff1a;https://v3.router.vuejs.org/zh/guide/ 尚硅谷视频&#xff1a;https://www.bilibili.com/video/BV1Zy4y1K7SH?p118 基本使用 安装&#xff1a; 这里安装vue3.x vue 2.x 版本对应 vue-router 3.xvue 3.x 版本对应 vue-router 4.x其他以此类推 npm…

【数据结构】------ 堆

目录 堆的概念及结构 堆的实现 堆向上调整算法 堆向下调整算法 堆的创建 堆的初始化和销毁 堆的插入 堆的删除 获取堆顶的数据 获取堆的数据个数 堆的判空 TopK问题&#xff08;在N个数找出最大&#xff08;小&#xff09;的前K个&#xff09; 堆排序 堆的概念及…

自学Python第二十七天- 简单部署生产环境,docker 的使用

自学Python第二十七天- 部署极简生产环境Windows 环境部署创建绿色 python 环境Linux 环境部署创建 Linux 环境使用Hyper-V使用 VMware 部署使用 docker 部署docker 原理安装 docker使用 linux 系统使用包管理工具使用 docker 仓库使用源代码安装使用 windows 系统开启 docker …

寻路算法-从bfs到Astart

一、简单BFS算法 bfs即广度优先搜索&#xff0c;最基础的寻路算法 即向出发点向四周无目的扩散&#xff0c;知道到达终点或者无法扩散为止 # coding: utf-8import random import bisectclass Solution(object):def __init__(self, n, m, bad):self.map [[0, 0, 0, 0, 0, 0, …

1.4. PUBLIC KEYS AS IDENTITIES公钥及身份 1.5. TWO SIMPLE CRYPTOCURRENCIES两种简单加密货币

《BITCOIN AND CRYPTOCURRENCY TECHNOLOGIES》Chapter 1系列 1.4. PUBLIC KEYS AS IDENTITIES 公钥作为身份 从一个签名方案中提取一个公钥将之视为一个身份。 公钥 public key 可以代表私钥 private key 的公众身份&#xff0c;而 private key 则是此人身份真实的内涵。 随时…

Linux服务搭建 -- NTP服务

什么是NTP&#xff1f; NTP全名“Network TimeProtocol”&#xff0c;即网络时间协议&#xff0c;是由RFC 1305定义的时间同步协议&#xff0c;用来在分布式时间服务器和客户端之间进行时间同步。 NTP基于UDP报文进行传输&#xff0c;使用的UDP端口号为123。使用NTP的目的是对网…

QFramework v1.0 使用指南 工具篇:03. CodeGenKit 脚本生成

在这一篇&#xff0c;我们学习几乎每个项目都要用到并且从中受益的功能&#xff1a;自动生成脚本并绑定&#xff0c;简称脚本生成。 基本使用 我们先在场景中&#xff0c;随便创建一些有父子结构的 GameObject&#xff0c;如下所示&#xff1a; 接着给 Player 挂上 ViewContr…

Spring 更简单的读取和存储对象

在 Spring 中想要更简单的存储和读取对象的核心是使用注解. 1.存储 Bean 对象 1.1 前置⼯作&#xff1a;配置扫描路径&#xff08;重要&#xff09; 注意&#xff1a;想要将对象成功的存储到 Spring 中&#xff0c;我们需要配置⼀下存储对象的扫描包路径&#xff0c;只有被配…

基于hadoop平台hive数据库处理电影数据

目录 1 开发背景 3 1.1开发背景与意义 4 1.2 开发环境与工具 4 2 可行性分析 7 2.1 可行性分析 8 2.2 需求可行性 8 2.3 技术可行性 8 2.4 操作可行性 8 2.5经济可行性 9 3 系统总体设计 10 3.1 总体设计方案 10 3.2 基础数据准备 10 3.3 环境准备 13 3.4 软件准备 13 4 系统详…

【文件操作详解】—— 一篇文章带你学会C语言的文件操作

文章目录1. 为什么要使用文件2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名3. 文件的打开和关闭3.1 文件指针3.2 如何打开和关闭文件3.2.1. 打开文件&#xff1a;fopen3.2.2 关闭文件&#xff1a;fclose3.2.3 补充4. 文件的顺序读写4.1 fputc4.2 fgetc4.3 fputs4.4 fgets4.…

(附源码)计算机毕业设计SSM基于Java网上玩具商店

&#xff08;附源码&#xff09;计算机毕业设计SSM基于Java网上玩具商店 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…