JDK12下的ArrayList源码解读 与 Vector的对比
ArrayList源码阅读.
//测试代码实现如下
private static void arrayList() {ArrayList<String> list = new ArrayList<String>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");list.add(1, null);int size = list.size();for (int i = 0; i < size; i++) {System.out.println(list.get(i));}}
查看ArrayList<String>();
的源码的时候可以发现如下:
- 其属性elementData被初始化为一个空的Object数组.
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
执行list.add("aaa");
可以看到如下源码:
其中的size表示目前List中已经存储的元素的数量,目前为0.
开始执行添加元素操作.
add(e, elementData, size);
protected transient int modCount = 0;
transient Object[] elementData; // non-private to simplify nested class access
private int size;
public boolean add(E e) {modCount++;add(e, elementData, size);return true;
}
进入add(e, elementData, size);
可以看到如下源码:
已存储元素和当前的对象数组的长度相等,都是0.
执行数组扩容行动
elementData = grow();
当目前对象数组已满时得到,
size==elementData.length
.进入
elementData = grow();
,继续扩容.通过最后两行代码给对象数组赋值.
private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;size = s + 1;
}
进入elementData = grow();
可以看到如下源码:
grow()
函数 调用grow(int minCapacity)
函数,其中传参的值,是目前需要的最小空间值.在经过
newCapacity
的计算之后将 新的对象数组的值,copy到elementData中.由此便完成了第一次扩容.最小值更新
minCapacity
为11
private Object[] grow(int minCapacity) {return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}
private Object[] grow() {return grow(size + 1);
}
进入newCapacity(minCapacity)
可以看到如下源码:
oldCapacity
旧容量的值设置为对象数组的长度,newCapacity
新容量的值设置为老容量+老容量的一次右移运算
.操作了半个小时结果发现
newCapacity
为0,然后进入if
循环,发现目前的elementData一点没动,其地址还是最初的时候赋值的DEFAULTCAPACITY_EMPTY_ELEMENTDATA.在默认容量
DEFAULT_CAPACITY=10
和最小容量minCapacity=1
之间选择一个最大值,也就是10.作为返回值.newCapacity
在经过右移运算后为15 . 然后执行就以15为最新的扩容值为准 返回.
private static final int DEFAULT_CAPACITY = 10;
private int newCapacity(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity <= 0) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)return Math.max(DEFAULT_CAPACITY, minCapacity);if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return minCapacity;}return (newCapacity - MAX_ARRAY_SIZE <= 0)? newCapacity: hugeCapacity(minCapacity);
}
Vector
的源码和ArrayList
对比只有一点的不同, 那就是Vector
在添加元素的时候加了线程锁, 是线程安全的.
public synchronized boolean add(E e) {modCount++;add(e, elementData, elementCount);return true;
}
总结: 其实就是扩容的操作解读, 赋值很简单. 而且源码的条例就是比我们自己写的好得多.
转载于:https://www.cnblogs.com/A-FM/p/10970743.html
JDK12下的ArrayList源码解读 与 Vector的对比相关推荐
- ArrayList源码解读
ArrayList源码解读 底层数据结构 ArrayList是在底层维护了一个elementData数组,添加了自动扩容等功能,最终形成了一个动态数组. 基本属性 // 初始化大小 private s ...
- java1.8 indexes_java1.8源码之ArrayList源码解读
文章目录 一.ArrayList概述1.1 ArrayList简介1.2 ArrayList数据结构 二.ArrayList源码分析2.1 ArrayList继承结构和层次关系2.2 类的属性2.3 ...
- Java Review - ArrayList 源码解读
文章目录 概述 方法的执行效率 源码剖析 底层数据结构 -数组 构造函数 自动扩容机制 set() get add()/addAll() remove() trimToSize() indexOf() ...
- 【集合详解】ArrayList源码解读之动态扩容
ArrayList 概述 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长. ArrayList不是线程安全的,只能用在单线程环境下. 实现了Serializable接口,因此它支 ...
- Java Review - PriorityQueue源码解读
文章目录 Pre PriorityQueue 概述 PriorityQueue 继承关系 PriorityQueue通过用数组表示的小顶堆实现 时间复杂度 构造函数 方法 add()和offer() ...
- Java Review - Queue和Stack 源码解读
文章目录 Pre 概述 Queue Deque ArrayDeque 一览 构造函数 属性 方法 addFirst() addLast() pollFirst() pollLast() peekFir ...
- Java Review - LinkedList源码解读
文章目录 Pre 概述 底层数据结构-双向链表 源码解析 构造函数 方法源码分析 getFirst() getLast() remove相关方法 remove(e) remove(index) rem ...
- ArrayList源码详细解析(一)
Java ArrayList源码解析(基于JDK 12,对比JDK 8) 自从接触到ArrayList以来,一直觉得很方便,但是从来没有系统.全面的学习了解过ArraryList的实现原理.最近学习了 ...
- Java 集合系列(2): ArrayList源码深入解析和使用示例
戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 上一章,我们学习了Collection的架构.这一章开始,我们对C ...
最新文章
- iOS开发笔记(十七):持久化方案之 NSUserDefaults
- qstring如何初始化_QString介绍
- tinyhttpd-0.1.0_hacking
- 安卓实训项目:基于储存卡音乐播放器实训报告4.0
- padding-bottom属性的作用
- Stern-Brocot Tree
- [html] html5中的meta标签http-equiv属性有什么作用?
- JME3中级手册一API特征映射1
- react开发_我如何在#100DaysOfCode挑战期间找到React开发人员的工作
- 透露一个未来3到5年的巨大商机
- win10 基础之上安装 Linux-Manjaro-Deepin 连夜采坑,快速整理下
- python如何测试rabbit_Python如何检测到我的RabbitMQ密码失败?
- txt文档下载另存为解决
- linux brctl
- 两步搞定经验模态分解与离散小波变换
- SpringBootJ2EE相关介绍
- day_05 运算符 if和while的使用
- 【快代理API】获取隧道代理IP
- android : 小米手机 打开开发者 选项 PC 端 安装 apk
- CAD闪退的解决方法
热门文章
- win32应用程序_不是有效的win32应用程序怎么解决
- mysql5_pn卸载_windows mySql(5.7.30) 卸载及重装
- tomcat出现5个using_出现急性心梗,要当心5个并发症,一个都不好惹!
- 翟萍python程序设计_Python程序设计(高等学校计算机教育规划教材)
- java qq音乐接口 api,QQ音乐解析API接口更新:支持HQ,ape,flac无损音质,缓存功能
- html5 呼吸灯效果,jQuery仿地铁线路指示灯效果
- 微信开发之自动回复图文消息
- 你连原理都还没弄明白?快来瞧瞧这份Spring面试小抄
- Eclipse的正确安装使用姿势
- python【蓝桥杯vip练习题库】ALGO-142 P1103(复数运算)