图解Arraylist内存分配,以及底层实现,扩容性能分析

Java语言程序设计与数据结构基础篇第8章课后习题实战代码详解 静态数组是指在声明时即确定大小的数组,其长度在整个生命周期内不可更改。这是与动态数组最本质的区别。在 Java 中,静态数组可以通过多种方式进行定义和初始化:// 方式一:先声明后创建int[] arr1;// 创建长度为5的整型数组,初始值全为0// 方式二:声明同时创建// 方式三:声明并初始化具体值(隐式指定长度)// 方式四:使用new关键字进行显式初始化上述代码展示了四种常见的数组初始化语法。其中,当仅指定长度时(如new int[5] 阅读详情
1:集合内存分配以及初始化过程图解
2:源码解读ArrayList内部实现(数组结构)
构造ArrayList的时候,默认初始化容量为10,保存容器为 Object[] elementData。
向集合添加元素的时候,调用add方法,比如list.add("a");
add方法做的操作是:elementData[size++] = e; 然后元素就被存放进了elementData。
初始化容量为10,当我们存第十一个元素的时候,会怎么做呢?看ArrayList类的部分源码:
public class ArrayList<E> extends AbstractList<E> implements List<E> {
	private transient Object[] elementData;
	
	public ArrayList(int initialCapacity) {
		super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
		this.elementData = new Object[initialCapacity];
    }
	//Constructs an empty list with an initial capacity of ten.
	public ArrayList() {
		this(10);
	}
	public boolean add(E e) {
		ensureCapacity(size + 1);  // 扩充长度
		elementData[size++] = e; // 先赋值,后进行size++。所以是从[0]开始存。
		return true;
	}
	public void ensureCapacity(int minCapacity) {
		modCount++;
		int oldCapacity = elementData.length; // 旧集合长度
		if (minCapacity > oldCapacity) {
			Object oldData[] = elementData; // 旧集合数据
			int newCapacity = (oldCapacity * 3)/2 + 1; // 计算新长度,旧长度的1.5倍+1
				if (newCapacity < minCapacity)
					newCapacity = minCapacity;
				// minCapacity is usually close to size, so this is a win:
				elementData = Arrays.copyOf(elementData, newCapacity); // 这就是传说中的可变集合。用新长度复制原数组。
		}
	}
	public E get(int index) {
		RangeCheck(index);
		return (E) elementData[index];
	}
}
add方法中先调用ensureCapacity方法对原数组长度进行扩充,扩充方式为,通过Arrays类的copyOf方法对原数组进行拷贝,长度为原数组的1.5倍+1。
然后把扩容后的新数组实例对象地址赋值给elementData引用类型变量。扩容完毕。
3:扩容性能简单分析
可以看到,扩容长度是旧长度的1.5倍+1,可以通过下面的程序计算出扩容次数:
public class Test {
	public static void main(String[] args) {
		increse(10, 1000);
	}

	private static int newCapacity; // 新容量
	private static int count; // 扩容次数
	private static int temp;
	
	/**
	 * 计算扩容次数
	 * @param init 集合初始化大小
	 * @param elementDataSize 元素个数
	 */
	public static void increse(int init, int elementDataSize) {
		temp = init;
		while (true) {
			if (newCapacity >= elementDataSize)
				break;
			increse(temp);
		}
	}
	private static void increse(int init) {
		newCapacity = (int) (init * 1.5 + 1); // 计算新容量
		System.out.println("扩容第 [" + ++count + "] 次" + "\t"
										+ "新容量=" + newCapacity);
		temp = newCapacity;
	}
}
经测试,如果要存100万数据,需要扩容28次,数据量越大,扩容次数越多,每一次的扩容代表着创建新数组对象,复制原有数据。

如果数据很大,那么有必要为集合初始化一个默认大小,防止多次扩容,但如果数据增长很慢,那么就会浪费内存了,具体怎么做,还是要看实际应用场景。这里只做初步分析。


原创文章,转载请注明出处:http://blog.youkuaiyun.com/thinking_in_android


ArcGIS小白必看:如何用3D Analyst工具将二维点线秒变三维模型(附详细步骤) 本文为ArcGIS初学者提供了利用3D Analyst工具将二维点、线数据快速转换为三维模型的完整指南。详细讲解了基于属性字段和数字高程模型(DEM)两种核心方法,并附上从数据准备、工具操作到三维场景可视化与问题排查的详细步骤,帮助用户轻松实现从平面到立体的空间数据建模。 阅读详情

相关推荐

右腿驱动电路设计:从共模干扰原理到生物电采集实战

在生物电信号采集领域,共模干扰是影响测量精度的核心挑战之一,其本质源于环境电磁场通过容性耦合在人体表面产生的感应电流。根据欧姆定律,由于人体组织阻抗的不均衡性,共模电流会在不同测量点产生差异化的压降,从而转化为难以滤除的差分噪声。为解决这一问题,右腿驱动技术应运而生,它通过负反馈原理主动抵消干扰,显著提升系统的共模抑制比。该技术广泛应用于心电图、脑电图等医疗电子设备中,是确保微弱生理信号质量的关键环节。本文结合工程实践,深入剖析了右腿驱动电路中的仪表放大器选型、反馈环路稳定性设计以及PCB布局布线要点,为高

weixin_31476015的博客 442

Arraylist的内存管理

在刚刚学习ArrayList的时候,我以为ArrayList的在内存中的存储形式是链表,但是学习中发现,它并没有链表那样灵活的元素插入的功能,因此查了一下它的内存存储方式,原来是一个动态的数组。 在声明一个ArraylList的时候,没有给ArrayList初始大小,Java虚拟机会自动给他分配一个默认的内存初始容量,初始容量为10。 ,当ArrayList的长度超过了10以后就会重新分配内存空...

kangshuangzhu的博客 737

在Kintex-7 FPGA上实现皮秒级时间测量:手把手教你搭建CARRY4进位链TDC(附源码与约束)

本文详细介绍了在Kintex-7 FPGA上利用CARRY4进位链实现皮秒级时间测量(TDC)的完整方案。从CARRY4的物理特性分析到硬件架构设计,再到校准方法与精度提升技巧,手把手教你构建测量精度达53ps的TDC系统,并附源码与约束文件,助力激光雷达、高能物理等精密计时应用开发。

weixin_42550052的博客 443

Java集合

Java集合 一、List List是一个有序、可重复的集合 List集合下最常见的集合类有两个:ArrayList和LinkedList 1、ArrayList ArrayList底层数据结构是数组。相较LinkedList,ArrayList查询效率高,增删效率低,原因是因为需要对数组进行复制。 ArrayList是线程不安全的,如果想要让ArrayList实现同步,可以使用Collections的方法Collections.synchronizedList来实现,或者使用另一个集合,CopyOnWri

qq_42985642的博客 356

Dify工作流教程|以抓取网页并更新知识库为例详细讲解工作流编排过程(附DSL文件)

{"name": "{新建的title变量}","text": "新建的content变量","indexing_technique": "high_quality","process_rule": {"mode": "automatic"}}有没有很痛苦,明明添加书签的网页,当你想阅读的时候,总是找不到或者好不容易找到了,发现网页404了。如果有个小工具,直接能把你输入的链接内容抓取下来,并且加入到你的知识库中,你说他香不香。无法获取授权的,也可以使用网页抓取工具,这个是免费的,抓取效果也可以。

同名公众号:dify实验室 1万+

IEEE Transaction期刊模板使用注意事项

本文将总结使用IEEE Transactions系列期刊的投稿模板时的一些注意事项,包括模板本身的使用规范、参考文献的正确格式等其他内容。

weixin_39529207的博客 2万+

Java中的ArrayList的初始容量和容量分配

List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。 ArrayList继承于List接口,除继承过来的方法外,还提供一些方法来操作内部用来存储列表的数组的大小。 每个ArrayList实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为...

u014754272的博客 408

沁恒CH32V30X学习笔记02--GPIO的使用教程及2次封装驱动

刚复位后,GPIO 口运行在初始状态,这时大多数 IO 口都是运行在状态所有的 GPIO 口都可以被配置外部中断输入通道,但一个外部中断输入通道最多只能映射到一个GPIO 引脚上,且外部中断通道的序号必须和 GPIO 端口的位号一致,,两方都是一对一的关系。复用功能。

Car12 705

集合---ArrayList的底层

集合---ArrayList的底层

温涛的博客 1735

zemax 如何编译用户自定义DLL(含VS下载教程)

zemax 如何编译用户自定义DLL(含VS下载教程)

weixin_72050316的博客 491

面试真题集(十六):TensorRT基础

TensorRT面试真题解析:从模型优化到推理部署 本文精选了14道TensorRT面试题,涵盖选择题、简答题和场景题,深度考察推理工程师对TensorRT核心技术的理解。内容聚焦三个关键维度: 基础概念 FP16推理中Softmax层为何需保持FP32(数值稳定性) INT8校准原理(EntropyCalibrator2的鲁棒性优势) Plugin V3接口的构建/运行分离设计 性能优化 Conv-BN-ReLU融合减少40-60%延迟的关键机制(访存优化) 动态Shape配置策略(min/opt/max

PeterPan的博客 69

java list原理_Java集合:ArrayList的实现原理

目录:一、ArrayList概述:ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWr...

weixin_30864831的博客 497

单片机应用案例:ESP32 搭配 BH1750 光强传感器和 Web 服务器

在该应用案例中,我们将使用 ESP32 开发板作为主控制器,BH1750 光强传感器用于采集环境光强度数据,并通过 Web 服务器展示采集到的数据。步骤一:购买材料步骤二:连接硬件步骤三:编写代码我们将使用 Arduino IDE 编写代码,以下是主要代码:// WiFi 设置const char* ssid = “你的 WiFi 名称”;const char* password = “密码”;// Web 服务器实例// BH1750 实例// 获取当前光强度数据。

RlDart的博客 812

java arraylist 内存_图解Arraylist内存分配,以及底层实现,扩容性能分析

1:集合内存分配以及初始化过程图解2:源码解读ArrayList内部实现(数组结构)构造ArrayList的时候,默认初始化容量为10,保存容器为 Object[] elementData。向集合添加元素的时候,调用add方法,比如list.add("a");add方法做的操作是:elementData[size++] = e; 然后元素就被存放进了elementData。初始化容量为10,当我们...

weixin_39681486的博客 677

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

图解Arraylist内存分配

1:集合内存分配以及初始化过程图解 2:源码解读ArrayList内部实现(数组结构) 构造ArrayList的时候,默认初始化容量为10,保存容器为 Object[] elementData。 向集合添加元素的时候,调用add方法,比如list.add("a"); add方法做的操作是:elementData[size++] = e; 然后元素就被存放进了elementDat

u010267179的专栏 2108

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

面试官问:ArrayList和LinkedList有什么区别?(附图解+比喻+避坑指南)

摘要:ArrayList基于动态数组(连续内存,O(1)随机访问),LinkedList基于双向链表(离散节点,头尾操作O(1))。本文用“高铁 vs 自行车队”比喻 + 源码级对比 + 时间复杂度全景表 + CPU缓存分析 + 5道面试官追问,彻底讲透这道Java集合必考题。一句话:查多改少用ArrayList,频繁头尾操作考虑LinkedList,中间插入两者都是O(n)。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 347

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

arrayList(一)

百度整理所得:ArrayList就是动态数组,也是一个对象。创建一个ArrayList对象,该对象存放在堆内存中,且是一个内存连续的内存区域。1、ArrayList是用数组实现的,这个数组的内存是连续的,不存在相邻元素之间还隔着其他内存。2、索引ArrayList时,速度比原生数组慢是因为你要用get方法,这是一个函数调用,而数组直接用[ ]访问,相当于直接操作内存地址,速度当然比函数调用快。3、...

star的博客 333

ArrayList和LinkedList集合有什么区别?

看到这个问题大家都觉得很简单是吗? ArrayList查询快!LinkedList增删快!很简单的问题不是吗? 这样回答的话当然是对的,但是还不够! 有的人可能会说ArrayList底层是一个数组,所以查询快,LinkedList底层是一个链表,所以增删快. 这样回答的话当然比第一个更好,但是还是不够! 那么到底怎么回答才全面呢?直接上图! 数组 链表 那么为什么数

浮华饰浮华的博客 4万+

Java数组与链表终极对决:底层原理、性能对比与实战选型!

数组是相同类型数据的有序集合,在内存中连续存储,通过**下标(索引)**访问。// 🟡 数组定义// 方式1// 方式2// 🟠 访问元素// O(1)// O(1)维度数组链表优势随机访问快、内存紧凑动态扩容、头/尾操作快劣势固定大小、中间插入删除慢随机访问慢、内存开销大适用场景频繁查询、固定/动态扩容小频繁头尾操作、大小动态变化Java推荐ArrayListLinkedList(但优先ArrayDeque核心记忆口诀🟡数组查改快(索引直接定位) + 🟠链表增删快(只改引用)

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 306

编程自学指南:java程序设计开发,List 集合,List 的三大特性,ArrayList动态数组的实现

编程自学指南:java程序设计开发,List 集合,List 的三大特性,ArrayList动态数组的实现

zl515035644的博客 949

java动态数组的作用_数据结构与算法系列1之数组介绍与动态数组实现

数据结构与算法系列1之数组介绍与动态数组实现数组基本概念介绍本节讲解顺序1数组的概念2数组的定义2.1动态初始化2.2静态初始化3数组中的内存划分4两个数组指向一个地址5两个常见问题1数组的概念数组是用来存储固定大小的同类型元素。2数组的定义2.1动态初始化1 public class Test {2 public static void main(String[] args) {3 ...

weixin_29959491的博客 240

java动态数组简介_数据结构与算法系列1之数组介绍与动态数组实现

数据结构与算法系列1之数组介绍与动态数组实现数组基本概念介绍本节讲解顺序1数组的概念2数组的定义2.1动态初始化2.2静态初始化3数组中的内存划分4两个数组指向一个地址5两个常见问题1数组的概念数组是用来存储固定大小的同类型元素。2数组的定义2.1动态初始化1 public class Test {2 public static void main(String[] args) {3 ...

weixin_42446705的博客 224

LinkedList 深入解析

本文将从定义、继承关系、源码深度解析、核心方法、迭代器、与 ArrayList 对比、面试高频考点全方位拆解 LinkedList,彻底搞清楚其底层设计与使用场景。

817

Android 面试准备进行曲(数据结构 Map /List)v1.1

Java数据结构 之 HashMap 重温学习 个人能力有限,暂时不整理温习 红黑二叉树 1. HashMap 参考文章 这里的HashMap 主要针对 JDK 1.8 版本,java 7 没有引入红黑树概念 HashMap 实际上是一个“链表散列”的数据结构,即数组和链表的结合体。它是基于哈希表的 Map 接口的非同步实现。 数组:存储区间连续,占用内存严重,寻址容易,插入删除困难; 链表...

魔都大白 589

数组与内存分析:Java程序员的“集装箱“操作指南

欢迎来评论区讨论,多回答才能印象更加深刻哦。:《面向对象入门 》

m0_58202543的博客 188

Java容器、并发编程、JVM

Java容器、并发编程、JVM

qq_39493185的博客 1846
上一篇: synchronized与ReentrantLock锁机制对比
下一篇: ThreadPoolExecutor线程池的使用与理解
flowciyu
博客等级 码龄15年 65粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值