ArrayList扩容机制

1.ArrayList继承的类和实现的接口

arraylist继承了AbstractList,实现了List接口、RandomAccess接口、Serializable接口

2.ArrayList类所包含的属性

(1)serialVersionUID

serialVersionUID适用于java序列化机制。简单来说,JAVA序列化的机制是通过 判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常,即是InvalidCastException。

private static final long serialVersionUID = 8683452581122892189L;

(2)DEFAULT_CAPACITY

默认初始容量为10

 /**
     * Default initial capacity.
     */ 
private static final int DEFAULT_CAPACITY = 10;

(3)EMPTY_ELEMENTDATA

将那句注释翻译下来为:用于空实例的共享空数组实例。说白了就是一个空数组

/**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

(4)DEFAULTCAPACITY_EMPTY_ELEMENTDATA

空数组的默认容量

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

(5)elementData

定义一个临时数组,即传过来的数组

transient Object[] elementData;

(6)size

集合中所储存元素的个数

private int size;

3.ArrayList中的方法

1)构造方法

【1】有参构造

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);
        }
    }

方法中定义了一个初始容量initialCapacity

在if条件判断中:(1)初始容量大于0(即不为空)时,new一个初始容量大小的Object数组

                            (2)当初始容量等于0(即为空)时,将空数组赋值给elementData

                            (3)都不是上述两种情况,就抛出一个异常

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;
        }
    }

参数为Collection<? extends E> c,是一个集合

1.将原集合转化成数组

2.在if中判断数组的长度:若长度不为0,将原集合中的数据复制到新数组

                                         若长度为0,返回一个空集合EMPTY_ELEMENTDATA

【2】无参构造

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

给elementData赋值一个空数组默认容量

2. add(E e)

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

[1]ensureCapacityInternal(int minCapacity)

private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

[2]ensureExplicitCapacity(int minCapacity)

这一步的目的是判断是否需要扩容

在if中判断最小容量与传进来的数组长度的大小,若最小容量大于传进来的数组长度,则调用grow()方法(具体方法见【4】

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

[3]calculateCapacity(Object[] elementData, int minCapacity)

这个方法的目的是获得最小容量

1.在参数中定义一个数组、一个最小容量

2.在if中判断传进来的数组是否与空数组的默认容量相等:

                                        相等:返回默认容量与最小容量之间最大的那个

                                        不相等:返回最小容量

private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

[4]grow(int minCapacity)

1.将传进来的数组长度定义为旧容量(oldCapacity)

2.将旧容量(oldCapacity)向右移一位,再加上原来的容量大小,即新容量(newCapacity)为原来的1.5倍

3.第一个判断中,将新容量(newCapacity)最小容量作比较,若小于最小容量(代表扩容过小),则将最小容量(minCapacity)赋给新容量newCapacity

4.第二个判断中,将新容量(newCapacity)MAX_ARRAY_SIZE作比较,若小于MAX_ARRAY_SIZE(代表扩容过大),则将hugeCapacity(int minCapacity)的返回值赋给新容量(newCapacity) (具体方法见【5】)

5.最后,将旧数组中的数据复制到新数组中(copyOf

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

[5]hugeCapacity(int minCapacity)

1.在if条件中,判断最小容量是否小于0:

          若小于0:则抛出异常

          否则:比较minCapacityMAX_ARRAY_SIZE的大小,大于(按源码中的顺序)则返回Integer.MAX_VALUE

                                                                                                     小于,则返回MAX_ARRAY_SIZ

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值