java集合之ArrayList源码解读
源自:jdk1.8.0_121
ArrayList继承自AbstractList,实现了List、RandomAccess、Cloneable、Serializable。
ArrayList内部是通过数组及数组的扩容来实现
变量
// 默认容量为10
private static final int DEFAULT_CAPACITY = 10;
// 空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 存放数据的数组,被transient修饰的参数不会被序列化
transient Object[] elementData;
// 实际元素的大小
private int size;
构造方法
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
toArray()实现方式的不同
注:
ArrayList(Collection<? extends E> c)之所以要判断是否为Object类型,是因为调用toArray()方法的实现方式不同。
在java.util.ArrayList中,toArray()返回的是Object数组。
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
在java.util.Arrays中,有个名为ArrayList的内部类,当调用Arrays.asList()时,返回的是java.util.Arrays$ArrayList内部类对象,而并非java.util.ArrayList。java.util.Arrays$ArrayList中的toArray()返回的虽然是Object数组,但它是有真是类型的数组。
private final E[] a;
public Object[] toArray() {
return a.clone();
}
ArrayList扩容
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// 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);
}
从源码可以看出,如果1.5倍的elementData.length小于10,会将elementData的大小扩容成默认的10,反之,则会以1.5倍的elementData.length进行扩容。
将elementData设置为实际容量,动态扩充的多余容量将被删除
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
java集合之ArrayList源码解读的更多相关文章
- 【源码阅读】Java集合之一 - ArrayList源码深度解读
Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章,从ArrayList开始第一篇. ---@pdai JDK版本 ...
- 【Java集合】ArrayDeque源码解读
简介 双端队列是一种特殊的队列,它的两端都可以进出元素,故而得名双端队列. ArrayDeque是一种以循环数组方式实现的双端队列,它是非线程安全的. 它既可以作为队列也可以作为栈. 继承体系 Arr ...
- Java集合干货——ArrayList源码分析
ArrayList源码分析 前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体 ...
- 【Java集合】ArrayList源码分析
ArrayList是日常开发中经常使用到的集合,其底层采用数组实现,因此元素按序存放.其优点是可以使用下标来访问元素,时间复杂度是O(1).其缺点是删除和增加操作需要使用System.arraycop ...
- Java集合之ArrayList源码分析
1.简介 List在数据结构中表现为是线性表的方式,其元素以线性方式存储,集合中允许存放重复的对象,List接口主要的实现类有ArrayList和LinkedList.Java中分别提供了这两种结构的 ...
- 死磕 java集合之ArrayList源码分析
欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可 ...
- Java集合(五)--LinkedList源码解读
首先看一下LinkedList基本源码,基于jdk1.8 public class LinkedList<E> extends AbstractSequentialList<E> ...
- Java 集合框架 ArrayList 源码剖析
总体介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现.除该类未实现同步外,其余跟Vector大致相同.每个ArrayL ...
- java集合: ArrayList源码浅析
ArrayList 是一个动态数组,线程不安全 ,允许元素为null. ArrayList的数据结构是数组,查询比较方便. ArrayList类的接口 public class ArrayList&l ...
随机推荐
- C# HttpClient设置cookies的两种办法 (转发)
一般有两种办法 第一种handler.UseCookies=true(默认为true),默认的会自己带上cookies,例如 var handler = new HttpClientHandler() ...
- ArrayList、Vector、LinkedList、HashMap、HashTable的存储性能和特性
ArrayList和Vector都是使用数组方式存储数据,次数组元素大于实际存储的数据以便添加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数 ...
- python入门(2)python的安装
python入门(2)python的安装 Python是跨平台的,可以运行在Windows.Mac和各种Linux/Unix系统上. 2.x还是3.x Python有两个版本,一个是2.x版,一个是3 ...
- 英语词汇周计划(1-1)group 1
abandon 1.He abandoned his wife and ten-year-old daughter. 2.abandon oneself to do sth 3.with abando ...
- django的模型类管理器-----------数据库操作的封装
模型实例方法 str():在将对象转换成字符串时会被调用. save():将模型对象保存到数据表中,ORM框架会转换成对应的insert或update语句. delete():将模型对象从数据表中删除 ...
- mangodb的基本操作:增删改差
MongoDB三元素: 1 数据库: 和关系型数据库中数据库的层次相同,内部可以有多个集合. 2 集合: 相当于关系型数据库中的表,存储若干文档,结构不固定 3 文档: 相当于关系型数据库中的行,是J ...
- nginx配置反向代理详细教程(windows版)
内容属于原创,如果需要转载,还请注明地址:http://www.cnblogs.com/j-star/p/8785334.html Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(I ...
- 前端 jQuery
一.jQuery是什么? <1>jQuery由美国人John Resig创建,至今已吸引了来自世界各地众多JavaScript高手加入其team. <2>jQuery是继pro ...
- oracle:批量插入不同方案对比
实时测试的速度: --48466条数据 --1.297 inline view更新法 inline view更新法就是更新一个临时建立的视图 update (select a.join_stateas ...
- flask 操作mysql的两种方式-sql操作
flask 操作mysql的两种方式-sql操作 一.用常规的sql语句操作 # coding=utf-8 # model.py import MySQLdb def get_conn(): conn ...