ArrayList 源码学习第一季

ArrayList 源码学习第一季

继承实现

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

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

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

  • 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 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 -

你可能感兴趣的:(学习,java)