ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢。 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧。

 public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L; //设置arrayList默认容量
private static final int DEFAULT_CAPACITY = 10; //空数组,当调用无参数构造函数的时候默认给个空数组
private static final Object[] EMPTY_ELEMENTDATA = {}; //这才是真正保存数据的数组
private transient Object[] elementData; //arrayList的实际元素数量
private int size; //构造方法传入默认的capacity 设置默认数组大小
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
} //无参数构造方法默认为空数组
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
} //构造方法传入一个Collection, 则将Collection里面的值copy到arrayList
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} //下面主要看看ArrayList 是如何将数组进行动态扩充实现add 和 remove public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} public void add(int index, E element) {
rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
} private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
} ensureExplicitCapacity(minCapacity);
} private void ensureExplicitCapacity(int minCapacity) {
modCount++; //超出了数组可容纳的长度,需要进行动态扩展
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} //这才是动态扩展的精髓,看到这个方法,ArrayList瞬间被打回原形
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
//设置新数组的容量扩展为原来数组的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,
//不够就将数组长度设置为需要的长度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//判断有没超过最大限制
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//将原来数组的值copy新数组中去, ArrayList的引用指向新数组
//这儿会新创建数组,如果数据量很大,重复的创建的数组,那么还是会影响效率,
//因此鼓励在合适的时候通过构造方法指定默认的capaticy大小
elementData = Arrays.copyOf(elementData, newCapacity);
} private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
} }

其实, ArrayList 的本质就是数组, ArrayList就是对数组进行动态的扩展,其add, get , remove 等等操作就是对数组的操作。至此,你还需要去记书籍上面所描述的ArrayList的特性了嘛? 如果还要记,那就弱爆了! ArrayList的一些特性都来源于数组:有序、元素可重复、插入慢、 索引快 等等一系列神马所谓的属性, 你懂了么?有木有恍然大悟的感觉

ArrayList其实就那么一回事儿之源码浅析的更多相关文章

  1. 【转】ArrayList其实就那么一回事儿之源码浅析

    转自:http://www.cnblogs.com/dongying/p/4013271.html?utm_source=tuicool&utm_medium=referral ArrayLi ...

  2. HashSet其实就那么一回事儿之源码浅析

    上篇文章<HashMap其实就那么一回事儿之源码浅析>介绍了hashMap,  本次将带大家看看HashSet, HashSet其实就是基于HashMap实现, 因此,熟悉了HashMap ...

  3. HashMap其实就那么一回事儿之源码浅析

    上篇文章<LinkedList其实就那么一回事儿之源码分析>介绍了LinkedList, 本次将为大家介绍HashMap. 在介绍HashMap之前,为了方便更清楚地理解源码,先大致说说H ...

  4. LinkedList其实就那么一回事儿之源码分析

    上篇文章<ArrayList其实就那么一回儿事儿之源码分析>,给大家谈了ArrayList, 那么本次,就给大家一起看看同为List 家族的LinkedList. 下面就直接看源码吧: p ...

  5. ArrayList源码浅析(jdk1.8)

    ArrayList的实质就是动态数组.所以可以通过下标准确的找到目标元素,因此查找的效率高.但是添加或删除元素会涉及到大量元素的位置移动,所以效率低. 一.构造方法 ArrayList提供了3个构造方 ...

  6. Code Reading: ORB-SLAM回环检测源码阅读+注释

    之前研究过一些回环检测的内容,首先要看的自然是用词袋回环的鼻祖和正当继承人(没有冒犯VINS和LDSO的意思)ORB-SLAM.下面是我的代码注释.因为代码都是自己手打的,不是在源码上注释的,所以一些 ...

  7. Java基础—ArrayList源码浅析

    注:以下源码均为JDK8的源码 一. 核心属性 基本属性如下: 核心的属性其实是红框中的两个: //从注释也容易看出,一个是集合元素,一个是集合长度(注意是逻辑长度,即元素的个数,而非数组长度) 其中 ...

  8. ArrayList类源码浅析(一)

    1.首先来看一下ArrayList类中的字段 可以看出,ArrayList维护了一个Object数组,默认容量是10,size记录数组的长度: 2.ArrayList提供了三个构造器:ArrayLis ...

  9. epoll 回显服务器源码

    在写epoll回显服务器代码之前,可以先看看上一篇文章:select poll epoll三者之间的比较.最近在继续学习网络编程中的服务端编程中,了解到很多网游服务器是在IOMP(IO完成端口)框架下 ...

随机推荐

  1. RAC One Node转换为RAC

    1.查看状态 [oracle@rone1 ~]$ srvctl config database -d rone Database unique name: rone Database name: ro ...

  2. 20145320《Java程序设计》第4周学习总结

    20145320<Java程序设计>第4周学习总结 教材学习内容总结 第六章 继承与多态 继承 继承作为面向对象的第二大特征,避免多个类间重复定义共同行为.即当多个类中存在相同属性和行为时 ...

  3. 配置Hibernate二级缓存

    首先找到配置EHCahe二级缓存需要添加的jar包 hibernate-release-4.1.9.Final→lib→optional→ehcache→下的ehcache-core-2.4.3.ja ...

  4. Android 实例子源代码文件下载地址380个合集

      android 城市列表特效 - 触摸查找源码 .rar: http://www.t00y.com/file/64337887 android 日记系统源码(数据库的基本操作) .rar: htt ...

  5. Grunt备忘录

    一.安装Grunt 应在全局环境下安装Grunt,以保障在任何目录下都能够正确找到grunt npm install grunt-cli -g 二.对已有Grunt基本目录结构文件进行操作 Grunt ...

  6. cargo failed to finish deploying within the timeout period [120000]

    cargo插件,报错:failed to finish deploying within the timeout period [120000] 解决方法:配置timeout为0 <plugin ...

  7. 欲实施CRM软件,必须先懂什么是CRM软件

    CRM是Customer Relationship Management(客户关系管理)的缩写,它是利用信息科学技术,实现市场营销.销售.服务等活动自动化,使企业能更高效地为客户提供满意.周到的服务, ...

  8. 学习Linux系列--安装Ubuntu

    最近学习Linux,使用虚拟机太不方便,于是购买了阿里云最便宜的云主机作为学习设备. 本系列文章记录了个人学习过程的点点滴滴. 学习Linux系列--安装Ubuntu 学习Linux系列--安装软件环 ...

  9. quick cocos2dx lua 内存释放

    前言 对于内存的优化,网上有很多例子和教程.总体来说,就那么几种解决方案,在最后我会简单提下,这里先说下在quick中,对于图片的处理. 1.查看内存调试信息 对于quick框架的了解,我们可以参考\ ...

  10. 有向图的强连通图——Kosaraju

    有向图的强连通分量: 相互可达关系,每一个集合都是有向图的一个强连通分量SCC. 把一个集合看成一个点,SCC就形成了一个有向无环图——DAG;       如果DFS选择不好,从A点开始DFS,就会 ...