Java--ArrayList源码剖析

本文深入探讨了ArrayList的工作原理,包括默认初始容量、动态扩展机制及其实现细节。对比了ArrayList与LinkedList的不同特性,帮助读者理解两者在不同场景下的适用性。

ArrayList底层是使用数组实现

   private static final Object[] EMPTY_ELEMENTDATA = {};

如果不指定大小,默认为10;

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

 

动态扩展数组大小原理:

minCapacity:需要的最小数组容量

每次进行扩充时

如果原来的数组的1.5倍大小 < 需要的大小,那么就将数组扩展为需要的大小。否则,扩展为原来的1.5倍大小(留点空间为了更好的插入数据)。

如果需要的大小 > Integer.MAX_VALUE - 8,那么就将数组大小调整为Integer.MAX_VALUE ;由此可见数组大小是可以到达int型的最大值的。

/**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */   
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); //oldCapacity * 1.5
        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;
    }

 elementData = Arrays.copyOf(elementData, newCapacity);将原来数组的数据复制到新的数组中,调用了Arrays.copyOf().其底层是用System.arraycopy()实现。

   public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

 

插入操作:

调用系统函数System.arraycopy()将原数组中index开始往后的元素都向后挪动了一位,然后把要插入的元素插入到指定位置。

    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

System.arraycopy() :常用作数组的扩容,如ArrayList底层数组的扩容。它是一个静态本地方法,由虚拟机实现,效率自然比用java一个个复制高。为浅复制,对于数组元素是对象,只会复制引用。

   * @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

ArrayList与LinkedList的比较:

LinkedList用链表实现,查询效率低增删效率高。

ArrayList用数组实现, 查询效率高增删效率低。

ArrayList线程不安全。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值