ArrayList原理解析 编辑
ArrayList扩容机制为什么是1.5倍+1
这里是自己参考jdk [version "1.8.0_144"] ,也是目前正在使用的
- 类实现
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
- 重要属性
* 默认初始容量 */ private static final int DEFAULT_CAPACITY = 10; /** * 用于空实例的共享空数组实例. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 用于默认大小的空实例的共享空数组实例,ArrayList的容量是此数组缓冲区的长度 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * 存储ArrayList元素的数组缓冲区. */ transient Object[] elementData; // 非私有,以简化嵌套类访问 /** * ArrayList的大小(它包含的元素数). */ private int size; /** * 结构修改的次数 */ protected transient int modCount = 0;
Java中transient关键字的作用,简单地说,就是让某些被修饰的成员属性变量不被序列化
1.基本属性概念
size是数据的个数!elementData.length是elementData的c长度(包含被元素占用的空间和预留的空间)
ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
将现在的长度size加一后,传进ensureCapacityInternal里面
2.初始化
DEFAULTCAPACITY_EMPTY_ELEMENTDATA是空数组,表示现在ArrayList是空的
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
ensureCapacityInternal中首先是判断现在的ArrayList是不是空的,如果是空的,minCapacity就取默认的容量和传入的参数minCapacity中的大值
然后调用ensureExplicitCapacity方法
3.fail fast机制
modCount是fail fast机制,在jdk1.6之前都是有volatile来修饰的,尽可能的让并发访问非安全的集合对象时尽快的失败抛出异常,让程序员修改代码
modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
在jdk1.7中去掉了volatile修饰,因为感觉没有必要为非线程安全集合浪费效率,在jdk1.5开始就提供了线程安全的集合类,在多线程环境下就应该使用线程安全的集合。
接着看,如果minCapacity的值大于add数据之前的大小,就调用grow方法,进行扩容,否则什么也不做
4.扩容的原理?
注意:这里传过来的minCapcatiy的值是size+1,能够实现grow方法调用就肯定是(size+1)>elementData.length的情况,所以size就是初始最大容量或上一次扩容后达到的最大容量,所以才会进行扩容
// overflow-conscious code int 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); }
newCapacity=oldCapacity+(oldCapacity>>1),这里就是扩容大小确定的地方,相当于新的最大容量是 size+1;size=1+0.5
相当于原来的1.5倍然后加1
-
参考文章
https://blog.csdn.net/JustForWorld/article/details/83119703
如果,您希望更容易地发现我的新文章,不妨点击一下绿色通道的【关注我】。
如果您觉得阅读本文对您有帮助,请点击一下右下方的推荐按钮,您的推荐将是我写作的最大动力!版权声明:本文为博主原创或转载文章,欢迎转载,但转载文章之后必须在文章页面明显位置注明出处,否则保留追究法律责任的权利。如您有任何疑问或者授权方面的协商,请 .
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档