ArrayList 源码学习第一季

ArrayList 源码学习第一季

继承实现

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
        // 忽略其他内容
        }

从上图我们即可得知,它实现了四个接口: List<E>, RandomAccess, Cloneable, java.io.Serializable; 以及继承了 AbstractList<E>.

那么这四个接口分别是干什么的呢?

  • List: List 相关接口,不用多做介绍
  • RandomAccess: 支持快速随机访问, 所在包: java.util
  • Cloneable: 支持对象克隆, 所在包: java.lang
  • Serializable: 序列化接口, 所在包: java.io

另外 AbstractList 这个类中定义了一些 List 的公共方法.

成员变量

   /**
     * 默认的初始容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 用于空实例的共享空数组实例
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * 用于默认大小的空实例的共享空数组实例。我们将此与 EMPTY_ELEMENTDATA 区分开来,以了解在添加第一个元素时要膨胀多少
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * 存储 ArrayList 元素的数组缓冲区。 ArrayList 的容量就是这个数组缓冲区的长度。      * 当添加第一个元素时,任何带有 elementData == DEFAULTCAPACITY_EMPTY_ELEME      * NTDATA的空 ArrayList 都将扩展为 DEFAULT_CAPACITY
     */
    transient Object[] elementData; // non-private to simplify nested class access  
  
    /**
     * ArrayList 的大小(它包含的元素数量)。
     */
    private int size;
  

注意点

  • EMPTY_ELEMENTDATADEFAULTCAPACITY_EMPTY_ELEMENTDATA

虽然这两个都是空数组,但不同在于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是可以扩容的,当有元素被添加到数组中时,DEFAULTCAPACITY_EMPTY_ELEMENTDATA 会扩容到 DEFAULT_CAPACITY 定义的大小;

ArrayList 初始化时可以选择传入初始大小,不传的话就会使用默认的 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,建议创建时显示赋值。

构造方法

代码如下:

  /**
   * 构造一个具有指定初始容量的空列表
   */
  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 的迭代器返回的顺序
   *
   */ 
  
  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;
        }
    }

事实上在实际使用过程中我们最常用的是无参的构造方法,但是如果可以预估出数组的大小,也可以传入一个预估的值,减少扩容的时间和内存消耗。

- END -
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值