List接口的具体实现类:ArrayList

List接口的具体实现类:ArrayList、LinkedList、Vector

ArrayList实现类的使用:

        1.ArrayList中参数可以是任何元素,包括null值

        2.ArrayList中的参数是可以重复的

        3.ArrayList底层是通过数组进行存储的

        4.ArrayList中存储数据是有序的(输出顺序与输入顺序一致)

ArrayList arrayList = new ArrayList();
arrayList.add("jack");
arrayList.add("tom");
arrayList.add(null);
arrayList.add("mary");
arrayList.add(null);
System.out.println("arrayList = " + arrayList); // [jack, tom, null, mary, null]

ArrayList底层源码分析:

        ArrayList中维护了一个Object[]类型的数组,通过数组存取数据

transient Object[] elementData; //transient表示瞬间、短暂的,该属性不会被序列化

        ArrayList类中提供了无参构造器和有参构造器,并规定了扩容机制

public ArrayList(int initialCapacity); //指定大小的构造器
    // 初始elementData容器大小为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
public ArrayList(); // 无参构造器
    // 初始elementData容器大小为0;首次添加后,容器大小为10;如果需要再次扩容,则扩容为1.5倍

                调用ArrayList中的无参构造器进行创建对象:

// 源码解读:
ArrayList arrayList = new ArrayList();
    /** 调用无参构造器,创建空数组elementData,size=0
     * public ArrayList() {
     *    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
     * }
     * private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
     */

for(int i = 0; i < 10; i++) {
    arrayList.add(i);
}
    /** 向数组中添加元素,执行arrayList.add方法
     *  public boolean add(E e) {
     *     // 首先判断是否需要对数组进行扩容处理
     *     ensureCapacityInternal(size + 1);  // Increments modCount!!
     *     // 后进行数组元素赋值
     *     elementData[size++] = e;
     *     return true;
     *  }
     */
    /** 首次添加元素(数组size=0)或数组长度不够用时,先进行扩容处理
     // 先调用ensureCapacityInternal方法
     * private void ensureCapacityInternal(int minCapacity) {
     *    // 确定数组需要进行扩容并计算数组扩容的大小
     *    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
     * }
     // 调用ensureExplicitCapacity方法,确定数组需要进行扩容
     * private void ensureExplicitCapacity(int minCapacity) {
     *     //记录数组被修改的次数,防止线程安全
     *     modCount++;
     *     // overflow-conscious code
     *     //最小容量-数组长度:当前数组的长度不够用的,调用grow方法进行扩容
     *     if (minCapacity - elementData.length > 0)
     *        grow(minCapacity);
     * }
     // 调用calculateCapacity方法,计算数组扩容大小
     * private static int calculateCapacity(Object[] elementData, int minCapacity) {
     *     //判断是不是空数组
     *     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
     *        //static final int DEFAULT_CAPACITY = 10; minCapacity = size+1
     *        return Math.max(DEFAULT_CAPACITY, minCapacity);
     *     }
     *     // 如果不是空数组,直接返回minCapacity=size+1
     *     return minCapacity;
     * }
     // 因此在calculateCapacity方法中,空数组扩容为10,不是空数组扩容为size+1
     // 调用grow方法,进行数组扩容
     *     private void grow(int minCapacity) {
     *         // overflow-conscious code
     *         int oldCapacity = elementData.length;
     *         int newCapacity = oldCapacity + (oldCapacity >> 1);
     *  //数组第一次扩容时,oldCapacity=0,所以newCapacity=0;
     *  //之后数组进行扩容,oldCapacity!=0,所以newCapacity=1.5*oldCapacity
     *         if (newCapacity - minCapacity < 0)
     *             newCapacity = minCapacity;
     * //newCapacity = 10
     *         if (newCapacity - MAX_ARRAY_SIZE > 0)
     *             newCapacity = hugeCapacity(minCapacity);
     *         // minCapacity is usually close to size, so this is a win:
     * //底层调用copeOf进行数组扩容,拷贝之前的数据进入新的elementData数组,防止丢失数据
     *         elementData = Arrays.copyOf(elementData, newCapacity);
     *     }
     */
// 因此首次添加元素,将数组扩容为10,之后数组长度不够时,按照长度的1.5倍进行扩容
// 数组长度变化:10 -> 15 -> 22 -> ....

                调用ArrayList的含参构造器进行创建对象:

ArrayList arrayList = new ArrayList(8);
    /* 调用ArrayList中的有参构造器,创建一个指定大小的数组
     * 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);
     *         }
     * }
     */

for (int i = 0; i <= 10; i++) {
    arrayList.add("hello" + i);
}
    /* 向数组中添加元素,调用add方法
     * 数组size=8,因此不需要直接对数组进行扩容处理
     * 当i==8时,数组已满,需要进行扩容处理
     * int newCapacity = oldCapacity + (oldCapacity >> 1):扩容为原来长度的1.5倍
     */

因此,调用无参构造器时,首先将数组扩容为10,之后按照1.5倍的速度对数组进行扩容;

        调用含参构造器时,数组初始化为参数值,数组长度不够时,按照1.5倍的速度进行扩容;

此外,ArrayList中的方法没有关键字synchronized修饰,线程不安全。(多线程不使用ArrayList)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值