ArrayList源碼2

ArrayList底層源碼詳解(擴展)

ArrayList(擴展)

除了常用的增刪改查,ArrayList還提了其他的操作集合的方法,他們的源碼實現通過這篇文章來進行解析。

  1. addAll(Collection<? extends E> c)將集合中的所有元素添加到當前集合的末尾。
      /**
       * 1. 將目標集合轉換爲數組
       * 2. 確保集合長度
       * 3. 將目標數組內容拷貝到當前數組的最後
       * 4. 更新集合的容量
       * 5. 根據目標數組的容量返回boolean判斷是否成功。
       */
      
      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);
       size += numNew;
       return numNew != 0;
   }

  1. addAll(int index, Collection<? extends E> c)將目標集合的元素從指定索引位置開始添加到當前集合中,並且將原本位置的元素向後移動目標集合長度的位置
      /**
       * 1. 將目標集合轉換爲數組
       * 2. 確保集合長度
       * 3. 計算元素需要移動的長度,然後將原本位置的元素向後移動指定長度。
       * 4. 將目標數組複製到index位置
       * 5. 根據目標數組的容量返回boolean判斷是否成功。
       *
       */
      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;
           if (numMoved > 0)
               System.arraycopy(elementData, index, elementData, index + numNew,
                                numMoved);
   
           System.arraycopy(a, 0, elementData, index, numNew);
           size += numNew;
           return numNew != 0;
       }
  1. removeAll(Collection<?> c)刪除當前集合和目標集合中元素相等的值。
       public boolean removeAll(Collection<?> c) {
           Objects.requireNonNull(c);
           return batchRemove(c, false);
       }
       
       
       private boolean batchRemove(Collection<?> c, boolean complement) {
           final Object[] elementData = this.elementData;
           int r = 0, w = 0;
           boolean modified = false;
           try {
               for (; r < size; r++)
                   //如果當前集合中不存在目標集合中的值,就將改元素存放到當前數組的w索引處
                   if (c.contains(elementData[r]) == complement)
                       elementData[w++] = elementData[r];
           } finally {
               // Preserve behavioral compatibility with AbstractCollection,
               // even if c.contains() throws.
               
               // 當c.contains() 拋出空指針異常的時候將r後的元素附加到w位置後面
               // 在某種情況下 c.contain()可能會拋出空指針的異常,出於安全考慮,進行如下操作
               //對於空指針下面的例子就會出現
               // public static boolean doesContain(Integer i) {
               //   return array.contains(Integer.toString(i));
               //   }
               //
               //    public static void main(String[] args) {
               //    System.out.println(doesContain(null));
               //  }
               
               if (r != size) {
                   System.arraycopy(elementData, r,
                                    elementData, w,
                                    size - r);
                   w += size - r;
               }
               
               //將剩餘元素清空
               if (w != size) {
                   // clear to let GC do its work
                   for (int i = w; i < size; i++)
                       elementData[i] = null;
                   modCount += size - w;
                   size = w;
                   modified = true;
               }
           }
           return modified;
       }

4 retainAll(Collection<?> c) 取目標集合和當前集合的交集

   // 此操作和remove相反 取相同的值 通過complement=true來控制
  
    public boolean retainAll(Collection<?> c) {
       Objects.requireNonNull(c);
       return batchRemove(c, true);
   }

5 replaceAll(UnaryOperator operator)將集合中所有的值替換爲指定值

       /**
        * UnaryOperator 通過傳入函數方法來進行替換值
        */
       @Override
       @SuppressWarnings("unchecked")
       public void replaceAll(UnaryOperator<E> operator) {
           Objects.requireNonNull(operator);
           final int expectedModCount = modCount;
           final int size = this.size;
           for (int i=0; modCount == expectedModCount && i < size; i++) {
               elementData[i] = operator.apply((E) elementData[i]);
           }
           if (modCount != expectedModCount) {
               throw new ConcurrentModificationException();
           }
           modCount++;
       }
       
       
       例子如下所示:
           List<Integer> list = Lists.newArrayList();
           for (int i = 0; i < 10; i++) {
               list.add(i);
           }
   
           list.replaceAll(a -> a + 10);
           System.out.println(list);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章