ArrayList分析
ArrayList概述
ArrayList继承了AbstractList,实现了List接口,底层基于动态数组,容量大小可以动态变化,ArrayList中可以添加null元素,另外,ArrayList是非线程安全的

ArrayList实现List, RandomAccess, Cloneable, java.io.Serializable接口。
- 实现RandomAccess接口,即标识着该类支持快速随机访问
 - 实现Cloneable接口,即覆盖了clone(),能被克隆
 - 实现Serializable接口,即ArrayList支持序列化,能被序列化去传输
 
ArrayList源码分析(基于jdk1.8)
成员变量
    /**
     * 默认容量为10
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     *存储ArrayList元素的数组缓冲区,ArrayList的容量是此数组缓冲区的长度。
   	 *添加第一个元素时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList都将扩展为默认容量
     */
    transient Object[] elementData;
    /**
     * ArrayList实际的元素个数
     */
	private int size;
构造方法
    /**
     	构造一个容量大小为10的空list,实际在第一次添加元素时才扩容到10
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    /**
     * 构造具有指定初始容量的空的list
     */
    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);
        }
    }
    //构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的
    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;
        }
    }
添加操作
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
	private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
扩容机制
//grow()方法是ArrayList扩容最终调用的代码
private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
     	//旧容量向右移1位,效果等同 oldCapacity*0.5
     	//新的容量是旧容量的1.5倍
        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);
    }
总结
构造一个空的,不指定容量 ArrayList  list = new ArrayList()的list时
当第一次调用add()方法向集合中添加元素时,才会扩容到10。
jdk1.6中ArrayList的扩容机制
- jdk1.6中是扩容成原来的1.5倍+1,代码: 
int newCapacity = (oldCapacity * 3)/2 + 1 - jdk1.7和jdk1.8都是扩容成原来的1.5倍
 
ArrayList扩容后是原来的数组还是新的数组
ArrayList扩容后是新的数组,当容量不够时,ArrayList底层通过Arrays.copyOf()方法将原来的数组拷贝到新的数组。因此,数据量多时,非常耗时。
Arrays.copyOf()内部调用System.arraycopy()方法
补充
ArrayList和Vector区别
- 线程安全:Vector的方法都是同步的,是线程安全的,而ArrayList不是线程安全的。由于同步会影响性能,所以,ArrayList的性能比Vector更好一些。
 - 扩容机制:ArrayList每次扩容是其大小的1.5倍,而Vector是其大小的2倍。
 
ArrayList和LinkedList区别
ArrayList和LinkedList都是实现List接口的容器类
- 底层数据结构:ArrayList是基于动态数组的数据结构,而LinkedList是基于双向链表的数据结构。
 - 随机访问效率:对于随机访问get和set,ArrayList要优于LinkedList,因为LinkedList要移动指针。
 - 空间花费:ArrayList的空间浪费主要体现在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。
 - 是否线程安全: ArrayList 和 LinkedList 都是不同步的,即不保证线程安全。
 
参考
https://blog.51cto.com/sihai/2073367
ArrayList分析的更多相关文章
- ArrayList分析1-循环、扩容、版本
		
ArrayList分析1-循环.扩容.版本 转载请注明出处 https://www.cnblogs.com/funnyzpc/p/16407733.html 前段时间抽空看了下ArrayList的源码 ...
 - ArrayList分析2 :Itr、ListIterator以及SubList中的坑
		
ArrayList分析2 : Itr.ListIterator以及SubList中的坑 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/16409137.html ...
 - Java集合源码学习(二)ArrayList分析
		
>>关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口,为什么叫&qu ...
 - Java源码之ArrayList分析
		
一.ArrayList简介 ArrayList底层的数据结构是数组,数组元素类型为Object类型,即可以存放所有类型数据. 与Java中的数组相比,它的容量能动态增长.当创建一个数组的时候,就必须确 ...
 - 集合ArrayList分析
		
目录 ArrayList 描述 重要的对象 遍历使用 与Collection关系 ArrayList属性 扩展:什么是序列化 transient关键字解析 ArrayList构造方法 无参构造 int ...
 - JDK源码分析(一)——ArrayList
		
目录 ArrayList分析 ArrayList继承结构 ArrayList字段属性 ArrayList构造函数 重要方法 ArrayList Iterator迭代器 总结 ArrayList分析 ...
 - ArrayList继承关系分析
		
目录 继承关系 Iterable Collection List AbstractCollection AbstractList RandomAccess Serializable Cloneable ...
 - ArrayList去除重复元素(包括字符串和自定义对象)
		
1.去除重复字符串 package com.online.msym; import java.util.ArrayList; import java.util.Iterator; @SuppressW ...
 - Java集合干货——LinkedList源码分析
		
前言 在上篇文章中我们对ArrayList对了详细的分析,今天我们来说一说LinkedList.他们之间有什么区别呢?最大的区别就是底层数据结构的实现不一样,ArrayList是数组实现的(具体看上一 ...
 
随机推荐
- Linux下删除文件系统空间不释放的问题
			
删除了Linux下的一个文件,但是系统空间并没有被释放. 如下:/home/hadmin/data/hadoop 使用了1.3T的空间,但是实际只使用了600多G 原因是我删除了一个600多G的文件, ...
 - 手机端获取用户详细地理位置(高德地图API)
			
项目开发需要获取用户详细的地理位置信息,使用了高德地图API接口 1,注册高德地图开发者账号获取开发者Key 2,页面调用 <script type="text/javascript& ...
 - cxf的一些使用说明
			
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agree ...
 - 安装一个Redis
			
1. 官网 http://redis.io/ 2.下载 官方不提供windows版本,但https://github.com/MSOpenTech/redis 可以从这里获取64位. 3.
 - MFC DestroyWindow[转]
			
考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...
 - UVA 11997 K Smallest Sums 优先队列 多路合并
			
vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一 ...
 - Python学习-5.Python的变量与数据类型及字符串的分割与连接
			
在Python中,变量类型是固定的,一旦声明就不能修改其类型(在Python里感觉不应该用声明,而应该用使用) 正确: var = 1 print(var) var = 2 print(var) 依次 ...
 - .Net Core IFormFile 始终为空的问题
			
之前获取上传文件都是使用Request.Form.Files获取,直到这次改成定义形参 IFormFile时才遇到这个问题. // POST api/values [HttpPost] public ...
 - Hibernate继承映射(@Inheritance)
			
继承映射在 Annotation 中使用 @Inheritance 注解,并且需要使用 strategy 属性指定继承策略,继承策略有 SINGLE_TABLE.TABLE_PER_CLASS 和 J ...
 - HBase原理–所有Region切分的细节都在这里了
			
本文由 网易云发布. 作者:范欣欣(本篇文章仅限内部分享,如需转载,请联系网易获取授权.) Region自动切分是HBase能够拥有良好扩张性的最重要因素之一,也必然是所有分布式系统追求无限 ...