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

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其实就那么一回事儿之源码浅析

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

  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. Yii2 – 如何写一个插件 , 如何做一个扩展

    原文地址: http://www.fancyecommerce.com/2016/05/10/yii2-%E5%A6%82%E4%BD%95%E5%86%99%E4%B8%80%E4%B8%AA%E6 ...

  2. MemberCached安装

    先上干货.. http://yunpan.cn/cmnABPWq27Mk7  访问密码 2ab3 这包里是安装包和一个比较合适的例子..例子是从CSDN上下载的..觉得对新手有帮助. 不过在这之前.. ...

  3. 【帖子】怎么彻底删除kafka的topic,然后重建?

    怎么彻底删除kafka的topic,然后重建? 网上都说用kafka-run-class.shkafka.admin.DeleteTopicCommand 命令删除topic,但是并没有成功,用kaf ...

  4. html中的 button,input-button, image, input-image的区别

    hmtl中 为了验证 form的 action提交属性, 是指 表单提交到的 页面, 可以是任意 性质的页面, 如:html页面, php页面, asp页面等都可以, 实际在测试的时候, 可以就写 提 ...

  5. VTK初学一,b_PolyVertex多个图形点的绘制

    #ifndef INITIAL_OPENGL #define INITIAL_OPENGL #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRend ...

  6. GATK软件介绍

    背景介绍 GATK全称是The Genome Analysis Toolkit,是Broad Institute(The Broad Institute, formerly the Broad Ins ...

  7. 真机调试 —— An unknown error occurred.

    iOS开发中,总会遇见各种各样的问题.今天我就在真机调试的时候出现 An unknown error occurred. 不知道什么鬼,百度一下,各种胡说八道. 解决办法: 1.退出Xcode,重新运 ...

  8. iOS设备 屏幕尺寸、操作系统、摄像头像素、发行时间 汇总

    设备 硬件尺寸 软件尺寸 精密程度 操作系统 摄像头像素 发行时间 iPhone 4s 640 x 960 320 x 480 2x iOS 5 800万 2011.10.04 iPhone 5 64 ...

  9. 吉他笔记 solo 和弦 推弦 音程

    十二平均律: 如下图所示: 第一行为唱名:do re mi fa so.... 第二行为音名:C #C D #D E F #F G #G A #A B C 第三行为D调对应的音名,即1 = D 第四行 ...

  10. FineUI第十八天---表格之事件的处理

    表格之事件的处理: 1.事件参数: GridPageEventArgs:表格分页事件参数,对应onPageIndexChange事件. NewPageIndex:新页面的索引 GridSortEven ...