ArrayList初始默认容量(长度)

本文深入探讨ArrayList的初始默认容量,说明为何默认为10,并分析ArrayList的扩容机制。通过源码解析,展示了ArrayList在JDK1.6和1.7的不同实现,包括容量增长策略的优化。同时,文章提到了ArrayList的构造函数、常用方法如add、remove、clear等的操作细节,强调了容量预估在性能优化中的重要性。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                       

  每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量。在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。 
  
  注意,此实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。这通常是通过同步那些用来封装列表的对象来实现的。但如果没有这样的对象存在,则该列表需要运用{@link Collections#synchronizedList Collections.synchronizedList}来进行“包装”,该方法最好是在创建列表对象时完成,为了避免对列表进行突发的非同步操作。

下面我们讨论下ArrayList初始默认容量的问题。
  
有文章说ArrayList默认构造的容量为10,没错。 因为ArrayList的底层是由一个Object[]数组构成的,而这个Object[]数组,默认的长度是10,所以有的文章会说ArrayList长度容量为10。

然而你所指的size()方法,指的是“逻辑”长度。 
所谓“逻辑”长度,是指内存已存在的“实际元素的长度”  而“空元素不被计算”

即:当你利用add()方法,向ArrayList内添加一个“元素”时,逻辑长度就增加1位。 而剩下的9个空元素不被计算。

如下代码:

ArrayList<String> list = new ArrayList<String>();  System.out.println("size = " + list.size());
  
  
  
  • 1
  • 2

输出结果如下:

size = 0
  
  
  
  • 1

ArrayList默认size()是0.

ArrayList源码解析

JDK版本不一样,ArrayList类的源码也不一样。

  • JDK1.8
ArrayList类结构
//通过ArrayList实现的接口可知,其支持随机访问,能被克隆,支持序列化public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
        //序列版本号    private static final long serialVersionUID = 8683452581122892189L;  //默认初始容量    private static final int DEFAULT_CAPACITY = 10;    //被用于空实例的共享空数组实例    private static final Object[] EMPTY_ELEMENTDATA = {};    //被用于默认大小的空实例的共享数组实例。其与EMPTY_ELEMENTDATA的区别是:当我们向数组中添加第一个元素时,知道数组该扩充多少。    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    /**     * Object[]类型的数组,保存了添加到ArrayList中的元素。ArrayList的容量是该Object[]类型数组的长度     * 当第一个元素被添加时,任何空ArrayList中的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA将会被     * 扩充到DEFAULT_CAPACITY(默认容量)。     */    transient Object[] elementData; //非private是为了方便嵌套类的访问    // ArrayList的大小(指其所含的元素个数)    private int size;    ......  }
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

ArrayList包含了两个重要的对象:elementData 和 size。

  1. elementData 是”Object[] 类型的数组”,它保存了添加到ArrayList中的元素。实际上,elementData是个动态数组,我们能通过构造函数 ArrayList(int initialCapacity)来执行它的初始容量为initialCapacity;如果通过不含参数的构造函数ArrayList()来创建 ArrayList,则elementData的容量默认是10。elementData数组的大小会根据ArrayList容量的增长而动态的增长,具 体的增长方式,请参考源码分析中的ensureCapacity()函数。

  2. size 则是动态数组的实际大小。

构造函数

ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回的顺序排列的。

     /**     * 构造一个指定初始容量的空列表     * @param  initialCapacity  ArrayList的初始容量     * @throws IllegalArgumentException 如果给定的初始容量为负值     */    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);        }    }    // 构造一个默认初始容量为10的空列表    public ArrayList() {        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;    }    /**     * 构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回的顺序排列的     * @param c 包含用于去构造ArrayList的元素的collection     * @throws NullPointerException 如果指定的collection为空     */    public ArrayList(Collection<? extends E> c) {        elementData = c.toArray();        if ((size = elementData.length) != 0) {            // c.toArray()可能不会正确地返回一个 Object[]数组,那么使用Arrays.copyOf()方法            if (elementData.getClass() != Object[].class)                //Arrays.copyOf()返回一个 Object[].class类型的,大小为size,元素为elementData[0,...,size-1]                elementData = Arrays.copyOf(elementData, size, Object[].class);        } else {            // replace with empty array.            this.elementData = EMPTY_ELEMENTDATA;        }    }
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

ArrayList构造一个默认初始容量为10的空列表:

  1. 初始情况:elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; size = 0;

  2. 当向数组中添加第一个元素时,通过add(E e)方法中调用的ensureCapacityInternal(size + 1)方法,即ensureCapacityInternal(1);

  3. 在ensureCapacityInternal(int minCapac

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值