JDK1.6 到JDK1.7,JDK1.8 ArrayList跟HashMap的变化

重点构造方法,有动扩容

(1)JDK1.6的构造方法JDK1.6 到JDK1.7,JDK1.8 ArrayList跟HashMap的变化_第1张图片
JDK1.8的构造方法

 /**
     * 初始化没有指定list大小,第一次插入的时候确定list容量的大小
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     */
    transient Object[] elementData;

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    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);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

构造函数确定是的 DEFAULTCAPACITY_EMPTY_ELEMENTDATA={},在初始化的时候没有指定ArrayList大小(注释里面有说明)
(2)JDK1.8的**add(E e)方法,这里有一个手动扩容方法ensureCapacity()**可以供外部调用

/*
* add 第一次添加元素确定集合大小
*/
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
/*
* add 添加元素调用ensureCapacityInternal确定集合大小
* 在默认的10跟添加元素数量取一个大的
*/
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

/*
* 确保明确的容量 (JDK1.8)为了确保集合不会溢出
* 调用grow()方法扩容
*/
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
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);
    }

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }
/*
* 确保明确的容量 (JDK1.6)
* 这是重点
*/
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
            newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

我们看到他们好像是一样的但是我们忘了在java世界里面 A>B 并不等于A-B>0因为有可能有内存溢出的风险。
调用手动扩容可以减小自动扩容带来的性能的降低,这是1.6开始有的新特新。

你可能感兴趣的:(java基础)