ArrayList的add方法實現


        ArrayList的底層是由數組實現,所以所有的操作都是圍繞數組展開,要想理解add方法,就得先了解數組的增加,所以我們先實現一個數組的add,數組的添加可以從尾部增加或者其他位置插入,

如果在數組的尾部插入,只需要拿到數組的長度,直接在該索引處賦予元素值,下面自己手動簡單實現一個在數組任意位置實現數組元素添加:

public class MyArray {
   public static void main(String[] args) {
         /*創建一個數組*/
         Object[] objectArray = new Object[10];
         for (int i = 0; i < 10; i++) {
             objectArray[i] = i;
         }
         System.out.println("原數組");
         for (int i = 0; i < objectArray.length; i++) {
            System.out.print(objectArray[i] + ",");
         }
         System.out.println();
         System.out.println("插入后的數組");
         Object[] newArray;
         try {
            newArray = MyArray.add(objectArray, 3, "hello");
            for (int i = 0; i < newArray.length; i++) {
                System.out.print(newArray[i] + ",");
            }
         } catch (Exception e) {
            e.printStackTrace();
         }
   }
   /*在一個數組的任意位置插入一個元素*/
   public static Object[] add(Object[] objectArray, int index, Object object) throws Exception {
       if(index < 0 || index - objectArray.length > 0) {
           throw new Exception("數組索引無效" + index);
       }
       Object[] newObjectArray = new Object[objectArray.length];
       /*首先將插入位置之前的所有元素拷貝到一個新的數組中*/
       for (int i = 0; i < index; i++) {
           newObjectArray[i] = objectArray[i];
       }
       /*然后將剩下的元素拷貝到插入位置加1后面的位置*/
       for (int i = index + 1; i < objectArray.length; i++) {
           if(!"".equals(objectArray[i])) {
              newObjectArray[i] = objectArray[i - 1];
           }
       }
       /*將新增的元素放到插入的位置*/
       newObjectArray[index] = object;
       return newObjectArray;
   }
}

(1) add方法

      如果想在數組的任意位置插入元素,我們需要建立一個新的數組,將插入位置前面的元素拷貝到新數組中,將插入位置后面的元素的下標都后移一位,將插入位置騰出,

將需要插入的元素放入該位置,比起上面的demo,ArrayList的實現稍微復雜,在上述的過程中加入了擴容機制,也不會上面一樣將一個數組整個復制到另一個新數組中,

而是原來數組插入位置后面的元素按順序復制到原數組插入位置+1的位置,下面為ArrayList的add方法源碼:

    public void add(int index, E element) {
        /*判斷插入的索引是否符合ArrayList范圍,在0 和 size之間,size是ArrayList實際元素個數,不包括底層數組的null元素*/
        rangeCheckForAdd(index);
        /*擴容機制:判斷添加是否需要進行擴容*/
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        /*將舊數組拷貝到一個新數組中,參數:被復制的原數組, 被復制數組的第幾個元素開始復制, 復制的目標數組, 從目標數組index + 1位置開始粘貼, 復制的元素個數,*/
        System.arraycopy(elementData, index, elementData, index + 1, size - index);           
        /*將新元素賦予該下標*/
        elementData[index] = element;
        /*元素個數+1*/
        size++;
    }

(2) addAll()方法

       ArrayList的addAll()方法的實現和add()方法實現思路一致,只不過需要移動的元素更多,由於數組結構的特性,導致這樣的操作對於數據大的ArrayList的插入操作,

會嚴重影響代碼執行的效率,所以開發中我們應該盡量避免出現對數據元素多的ArrayList頻繁add。

 public boolean addAll(Collection<? extends E> c) {
            /*轉為對象數組*/
            Object[] a = c.toArray();
            int numNew = a.length;
            /*擴容機制:判斷是否需要擴容*/
            ensureCapacityInternal(size + numNew);  // Increments modCount
            /*拷貝數組,參數:被復制的數組,被復制數組的第幾個元素開始復制,復制到目標數組,目標數組粘貼的位置, 復制的個數*/
            System.arraycopy(a, 0, elementData, size, numNew);
            /*數組長度+numNew*/
            size += numNew;
            return numNew != 0;
        }
   public boolean addAll(int index, Collection<? extends E> c) {
       /*判斷索引是否有效*/
       rangeCheckForAdd(index);
       Object[] a = c.toArray();
       int numNew = a.length;
       /*擴容機制:判斷是否需要擴容*/
       ensureCapacityInternal(size + numNew);  // Increments modCount
       /*需要移動的元素個數*/
       int numMoved = size - index;
       /*如果插入位置不在尾部,則移動原數組index以后的元素,未插入c騰出空間,如果在尾部,與addAll(Collection<? extends E> c)方法相同*/
       if (numMoved > 0)
           System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
       /*將需要插入的數組插入到騰出空間中*/
       System.arraycopy(a, 0, elementData, index, numNew);
       /*長度+numNew*/
       size += numNew;
       return numNew != 0;
   }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM