ArrayList的源码分析(基于jdk1.8)
1.初始化
transient Object[] elementData; //实际存储元素的数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
//初始化为一个默认的空数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
2. 添加元素
private static final int DEFAULT_CAPACITY = 10;//默认容量
public boolean add(E e) {
//确保当前数组的容量是够得
ensureCapacityInternal(size + 1); // Increments modCount!!
//将新元素添加到[size++]的位置
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//如果是第一次添加
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//扩容为默认容量大小:10
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//每一次添加都要判断是否需要扩容
ensureExplicitCapacity(minCapacity);
}
3.扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// 先获取当前数组的容量
int oldCapacity = elementData.length;
//新容量为当前容量 + 当前容量的一半
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 拷贝原数组中的元素至新数组,并返回新数组的引用
elementData = Arrays.copyOf(elementData, newCapacity);
}
4.结论
ArrayList物理结构是数组,决定了它的存储特点是:需要开辟连续的存储空间来存储元素,当存储容量不够时,需要扩容,增加容量为原来的1.5倍。类似的,Vector的物理结构也是数组,当存储容量不够时,需要扩容为原来的2倍。那么是1.5倍好呢?还是2倍好呢?1.5倍使得数组空间使用率提高了,但是这也增加了扩容的频率。所以,建议大家在选择动态数组时,如果对要存储的元素个数有一个预估时,那么可以在创建ArrayList时,就使用ArrayList(int initialCapacity) 构造器,避免反复扩容。
ArrayList的源码分析(基于jdk1.8)的更多相关文章
- HashMap 源码分析 基于jdk1.8分析
HashMap 源码分析 基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table; //这里维护了一个 Node的数组结构: 下面看看Node的数 ...
- CopyOnWriteArrayList 源码分析 基于jdk1.8
CopyOnWriteArrayList 源码分析: 1:成员属性: final transient ReentrantLock lock = new ReentrantLock(); //内部是 ...
- HashMap源码分析-基于JDK1.8
hashMap数据结构 类注释 HashMap的几个重要的字段 hash和tableSizeFor方法 HashMap的数据结构 由上图可知,HashMap的基本数据结构是数组和单向链表或红黑树. 以 ...
- ArrayList 源码分析 基于jdk1.8:
1:数据结构: transient Object[] elementData; //说明内部维护的数据结构是一个Object[] 数组 成员属性: private static final int ...
- LinkedList的源码分析(基于jdk1.8)
1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...
- ArrayList的源码分析
在项目中经常会用到list集合来存储数据,而其中ArrayList是用的最多的的一个集合,这篇博文主要简单介绍ArrayList的源码分析,基于JDK1.7: 这里主要介绍 集合 的属性,构造器,和方 ...
- AtomicInteger源码分析——基于CAS的乐观锁实现
AtomicInteger源码分析——基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时 ...
- 并发-AtomicInteger源码分析—基于CAS的乐观锁实现
AtomicInteger源码分析—基于CAS的乐观锁实现 参考: http://www.importnew.com/22078.html https://www.cnblogs.com/mantu/ ...
- ArrayList迭代器源码分析
集合的遍历 Java集合框架中容器有很多种类,如下图中: 对于有索引的List集合可以通过for循环遍历集合: List<String> list = new ArrayList<& ...
随机推荐
- 二阶SQL注入理解与体会
一:SQL注入分类 SQL注入一般分为两类:一阶SQL注入(普通SQL注入),二阶SQL注入 二:二者进行比较 0x01:一阶SQL注入: 1:一阶SQL注入发生在一个HTTP请求和响应中,对系统的攻 ...
- yii2.0查询关联数据以及widgets小部件
怎样去查询关联数据呢,接下来整理一个简单的代码:
- June 18th 2017 Week 25th Sunday
Life was like a box of chocolates, you never know what you're gonna get. 人生就像一盒巧克力,结果往往出人意料. Compare ...
- Ubuntu Tweak (linux下的优化大师)
Ubuntu Tweak 是中国人开发的一款专门为Ubuntu准备的配置.调整工具,它类似与compiz,但是界面更友好. 下面是安装命令: 第一步:添加tweak源 sudo add-apt-rep ...
- servlet api.jar是干什么的?
支持servlet的jar包.应该叫servlet-api.jar你如果编写过servlet就知道要用到HttpServletRequest和HttpServletResponse等对象,这些对象都是 ...
- 阅读《C陷阱与缺陷》的知识增量
版权声明:本文为Focustc原创文章.转载请注明作者及出处. https://blog.csdn.net/caozhankui/article/details/35925939 看完<C陷阱与 ...
- 网络解析json
public class myActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceSta ...
- 针对Restful风格参数传递的请求获取真实url
昨天遇到这样一个问题,先简单介绍下. 业务场景 我们想要统计热点请求URL,进而进行分析优化 方案 通过过滤器获取到请求url(调用方法request.getservletpath),通过redis进 ...
- [19/04/06-星期六] 多线程_静态代理(StaticProxy)和 lamda (简化代码,jdk8新增)
一.静态代理 [代码示例] /*** * 静态代理:记录日志等,类是写好的,直接拿来用. 动态代理:随用随构建,临时抱佛脚 * 婚庆公司:代理角色,帮你搞婚庆的一切,布置房间等等 * 自己:真实角色, ...
- 查找连接过的USB存储设备
gp "HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR\*\*"|select friendlyname,CompatibleIDs,mfg ...