【Java Collection】常見 List 子類剖析(三)

我的原則:先會用再說,內部慢慢來。
學以致用,根據場景學源碼


一、架構

1.1 常見子類 UML

在這裏插入圖片描述

1.2 簡述


二、 RandomAccess 接口子類

2.1 ArrayList 類

2.2 Vector 類

2.3 CopyOnWriteArrayList 類

2.4 ImmutableList 類

=== 點擊查看top目錄 ===


三、 AbstractSequentialList 抽象類子類

3.1 LinkedList 類


四、ArrayList 類

在這裏插入圖片描述

  • java.util.ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 注意:實現了 RandomAccess,表明是支持隨機訪問,那麼也就是內部是數組Array 結構。

4.1 變量

變量名 備註
private static final int DEFAULT_CAPACITY = 10 內部Array數組默認長度,不夠再擴容。
private static final Object[] EMPTY_ELEMENTDATA = {} 空數組。(標誌性的)構造方法、trimToSize 、readObject用到
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 確定容量用的。我們將此與EMPTY_ELEMENTDATA區分開來,以瞭解在添加第一個元素時要膨脹多少。ensureCapacity、calculateCapacity 用到
transient Object[] elementData 元素數組
private int size 數組長度

=== 點擊查看top目錄 ===

4.2 方法

4.2.1 初始化(3個)
  • 默認構造方法
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
  • 帶initialCapacity構造方法
    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);
        }
    }
  • 帶 Collection 的構造方法
    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;
        }
    }
  • 三構造方法,注意一下 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 與 EMPTY_ELEMENTDATA 的區別,前面那個是默認的。

=== 點擊查看top目錄 ===

3.2.2 get 與 set 方法
    public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }
   public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

都是先檢查下標是否溢出,然後再進行 get 或者 set。

=== 點擊查看top目錄 ===

4.2.3 add 方法
  • java.util.ArrayList#add(E)
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
  1. 先檢查數組內部容量 ensureCapacityInternal
  2. 設置元素

=== 點擊查看top目錄 ===

4.2.4 ensureCapacityInternal 方法
  • java.util.ArrayList#ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
  1. calculateCapacity 先計算所需要數組容量
  2. ensureExplicitCapacity 確保容量充足,必要時候擴容
4.2.5 calculateCapacity 方法
  • java.util.ArrayList#calculateCapacity (計算所需要數組容量 )
private static int calculateCapacity(Object[] elementData, int minCapacity) {
		// 若是默認的,也即是調用了
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
  1. ArrayList默認構造方法下,會進行擴容到合適的容量。
  2. 返回最少需要的容量
  • 上層調用:
    -
  1. ensureCapacityInternal 確保合適容量
  2. readObject 從輸入流轉換成 List 會用到

=== 點擊查看top目錄 ===

4.2.6 ensureExplicitCapacity 方法
  • java.util.ArrayList#ensureExplicitCapacity
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
  1. modCount++ ,那麼加入你在Iterator遍歷,那麼你就會拋出 ConcurrentModificationException
  2. 判斷是否能夠裝下新元素,不夠的話就 grow

=== 點擊查看top目錄 ===

4.2.7 grow 方法
  • java.util.ArrayList#grow
  • 容量增長方法,內部是調用 native 方法進行復制。
    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);
    }
  • 此處應該注意,如果每次添加一個元素都要進行擴容的話,那麼及其浪費性能。

=== 點擊查看top目錄 ===

4.2.8 remove 方法
方法名 備註
public E remove(int index) 按 index 刪除
public boolean remove(Object o) 按 Object 刪除
public boolean removeIf(Predicate<? super E> filter) 按條件刪除
protected void removeRange(int fromIndex, int toIndex) 刪除一定範圍內的元素
public boolean removeAll(Collection<?> c) 批量刪除
  • java.util.ArrayList#remove(int) 刪除 index 下標的元素
public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

內部原理:

  1. 拿到老的 Element ,待會返回
  2. 使用 native 底層的複製方法,把 index+1 以及後面的元素全部複製到index的位置來。
  3. 最後一個元素設置爲null
  4. size - 1

=== 點擊查看top目錄 ===

  • java.util.ArrayList#remove(java.lang.Object) 刪除某個元素
public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

內部原理:

  1. 拿到老的 Element
  2. 使用 native 底層的複製方法,把 index+1 以及後面的元素全部複製到index的位置來。fastRemove方法
  3. 最後一個元素設置爲null
  4. size - 1
  5. return true / false
  • 注意一下:若有100w個數據,你從頭刪到尾巴,那麼肯定非常耗時。因爲每次都要進行復制。

=== 點擊查看top目錄 ===

4.2.9 removeAll 方法
  • java.util.ArrayList#removeAll
  • 把Collection中包含c集合中的元素都移除掉(求差集)
public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }

=== 點擊查看top目錄 ===

4.2.10 batchRemove 方法(private)
  • java.util.ArrayList#batchRemove
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++)
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            // r != size 的情況: c.contains() 丟出 Exception,(看下 java.util.AbstractCollection#contains )
            if (r != size) {
                // 如果丟出異常,那麼把後面沒處理的都給銜接上放在原 elementData 上面
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            // retainAll 情況下:如果 w == size ,那麼說明原來的Collection 與要處理的 Collection 一模一樣
            // removeAll 情況下:如果 w == size ,那麼一個沒刪除
            // 那麼 w!= size 是什麼情況呢?就是上面for處理後,w 後面還有元素,後面的元素都不要了,需要設置爲 null,協助 gc
            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;
    }
  • 看下上層引用
    在這裏插入圖片描述
  • retainAll 與 removeAll
for (; r < size; r++)
       if (c.contains(elementData[r]) == complement)
            elementData[w++] = elementData[r];

---
retainAll:

elementData : A B C D F G
c : A C E

size = 10 
elementData : A C 
---

removeAll:

elementData : A B C D F G
c : A C E

size = 10 
elementData : B D F G

=== 點擊查看top目錄 ===

4.2.11 retainAll 方法
  • java.util.ArrayList#retainAll 方法
  • 把Collection中不是c的元素移除掉(求合集)
    public boolean retainAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, true);
    }

=== 點擊查看top目錄 ===

4.2.12 trimToSize 方法
  • java.util.ArrayList#trimToSize 方法
  • 壓縮容量,假如內存1w的數組裏面只有1000個元素,調用這個方法就是把這1000個元素copy到另外一個新的數組,指針指向這個新的數組。
public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
    }

=== 點擊查看top目錄 ===

4.2.13 fastRemove 方法 (private)
  • java.util.ArrayList#fastRemove 方法
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }
4.2.14 clear 方法
  • java.util.ArrayList#clear 方法
    public void clear() {
        modCount++;
        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }
  1. 數組內元素指針全部指向null,協助GC
  2. size 設置爲 0
  • 思考下,爲什麼不直接 elementData = null

我自己的看法:如果你不想用這個list了,那麼直接 list = null,如果你還想用,那麼就調用 clear,免得你待會還得再 new 一個。

=== 點擊查看top目錄 ===

4.2.15 subList 方法
  • java.util.ArrayList#subList 方法
  • 淺複製,得到子List,實際上操作的還是父本身的list內部元素,詳情看內部類 subList 實現
public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }

static void subListRangeCheck(int fromIndex, int toIndex, int size) {
    if (fromIndex < 0)
        throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
    if (toIndex > size)
        throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    if (fromIndex > toIndex)
        throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                           ") > toIndex(" + toIndex + ")");
}

=== 點擊查看top目錄 ===

4.2.16 writeObject 方法
  • java.util.ArrayList#writeObject 方法
  • 將 Collection 寫入輸出流 ObjectOutputStream
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

=== 點擊查看top目錄 ===

4.2.17 readObject 方法
  • java.util.ArrayList#readObject 方法
  • 將輸入流 ObjectInputStream 寫入Collection
private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            int capacity = calculateCapacity(elementData, size);
            SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
            ensureCapacityInternal(size);

            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }
    }

4.2.18 爲什麼elementData是transient的?

ArrayList變量表

  1. ArrayList在序列化的時候會調用writeObject,直接將size和element寫入ObjectOutputStream;反序列化時調用readObject,從ObjectInputStream獲取size和element,再恢復到elementData。
  2. 爲什麼不直接用elementData來序列化,而採用上訴的方式來實現序列化呢?原因在於elementData是一個緩存數組,它通常會預留一些容量,等容量不足時再擴充容量,那麼有些空間可能就沒有實際存儲元素,採用上訴的方式來實現序列化時,就可以保證只序列化實際存儲的那些元素,而不是整個數組,從而節省空間和時間。

=== 點擊查看top目錄 ===

4.2.19 toArray 方法
  • java.util.ArrayList#toArray() 方法
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }
  • java.util.Arrays#copyOf(T[], int) 方法
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
  • java.util.Arrays#copyOf(U[], int, java.lang.Class<? extends T[]>) 方法
    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;
    }
  • java.lang.System#arraycopy
  • 底層是深複製
 public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
  • List內部也是數組Array,複製的底層就是調用 System#arraycopy 將List內部數組複製成一個新的Object數組
    === 點擊查看top目錄 ===
4.2.20 size 方法
  • java.util.ArrayList#size 方法
    public int size() {
        return size;
    }

=== 點擊查看top目錄 ===

4.3 是否指定 capacity 帶來的區別

private static void test01() {
    ArrayList<String> stringList = new ArrayList<>(100000000); // 162ms 
    ArrayList<String> stringList = new ArrayList<>(1); //  9000ms

    long begin = System.currentTimeMillis();

    for (int i = 0; i < 100000000; i++) {
        stringList.add("A");
    }

    long end = System.currentTimeMillis();
    System.out.println("ArrayList -> " + (end - begin));
}
  • 162ms VS 9000m ,原因就是內部的 copy 操作,每次擴容都會全量複製一次。

五、Vector 類

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 在 ArrayList 基礎上,所有方法加上 synchronized 。

=== 點擊查看top目錄 ===

六、CopyOnWriteArrayList 類

6.1 變量

變量 備註
final transient ReentrantLock lock = new ReentrantLock(); 寫的時候加鎖
private transient volatile Object[] array; 數組,存放元素,transient說明重寫了 readObject 與 writeObject 方法,目的是爲了不存儲空數據

6.2 代碼

  • 整體代碼:
package java.util.concurrent;

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    /** The lock protecting all mutators */
    final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;
    ...
}
  • 查詢方法相比 ArrayList 無任何改動。
  • 寫入方法:
6.2.1 set 方法
  • java.util.concurrent.CopyOnWriteArrayList#set 方法
public E set(int index, E element) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            E oldValue = get(elements, index);

            if (oldValue != element) {
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len);
                newElements[index] = element;
                setArray(newElements);
            } else {
                // Not quite a no-op; ensures volatile write semantics
                setArray(elements);
            }
            return oldValue;
        } finally {
            lock.unlock();
        }
    }
  • 注意
  1. 寫的時候,先上 lock
  2. Arrays.copyOf 內部使用 native 方法進行復制
  3. 替換掉老數組
  4. 釋放 lock

=== 點擊查看top目錄 ===

七、ImmutableList 類

  • 該類內的全部元素,一初始化便註定不能改變。
  • 元素不可改變的方法,任何一個寫操作都會拋出 UnsupportedOperationException .
  • 拋出異常的方法
方法 描述
add(E e) throw new UnsupportedOperationException()
remove(Object object) throw new UnsupportedOperationException();
addAll(Collection<? extends E> newElements) throw new UnsupportedOperationException();
removeAll(Collection<?> oldElements) throw new UnsupportedOperationException();
retainAll(Collection<?> elementsToKeep) throw new UnsupportedOperationException();
clear() throw new UnsupportedOperationException();
package com.google.common.collect;

@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // we're overriding default serialization
public abstract class ImmutableList<E> extends ImmutableCollection<E>
    implements List<E>, RandomAccess {
}

=== 點擊查看top目錄 ===

7.1 構造方法 ImmutableList

ImmutableList() {}
  • default 類型的構造方法,說明只供同一個 package 下的使用,真正的初始化方法是 of

7.2 初始化方法 of


  @SuppressWarnings("unchecked")
  public static <E> ImmutableList<E> of() {  return (ImmutableList<E>) EMPTY; }
  public static <E> ImmutableList<E> of(E element) {  return new SingletonImmutableList<E>(element);  }
  public static <E> ImmutableList<E> of(E e1, E e2) {   return construct(e1, e2);   }
  public static <E> ImmutableList<E> of(E e1, E e2, E e3) {   return construct(e1, e2, e3);  }
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {  return construct(e1, e2, e3, e4); }
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) { return construct(e1, e2, e3, e4, e5);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {return construct(e1, e2, e3, e4, e5, e6);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {return construct(e1, e2, e3, e4, e5, e6, e7);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return construct(e1, e2, e3, e4, e5, e6, e7, e8);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);}
  public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);}
  public static <E> ImmutableList<E> of( E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) {
    Object[] array = new Object[12 + others.length];
    array[0] = e1;
    array[1] = e2;
    array[2] = e3;
    array[3] = e4;
    array[4] = e5;
    array[5] = e6;
    array[6] = e7;
    array[7] = e8;
    array[8] = e9;
    array[9] = e10;
    array[10] = e11;
    array[11] = e12;
    System.arraycopy(others, 0, array, 12, others.length);
    return construct(array);
  }
  • 我還是沒搞懂爲什麼要寫那麼多個 of 方法,直接下面這樣不行嗎???
  public static <E> ImmutableList<E> of( E e1,E... others) {
    Object[] array = new Object[1 + others.length];
    array[0] = e1;
    System.arraycopy(others, 0, array, 1, others.length);
    return construct(array);
  }

=== 點擊查看top目錄 ===

7.3 construct 方法

  private static <E> ImmutableList<E> construct(Object... elements) {
    return asImmutableList(checkElementsNotNull(elements));
  }
  • private 與 static 表明是一個靜態私有構造方法,也就是該方法不會被外部調用。

7.4 checkElementsNotNull 方法

  • 該方法確保存入的元素 Element 不能爲 null
  • ArrayList 、LinkedList 、Vector 允許null元素
static Object[] checkElementsNotNull(Object... array) {
    return checkElementsNotNull(array, array.length);
  }

  static Object[] checkElementsNotNull(Object[] array, int length) {
    for (int i = 0; i < length; i++) {
      checkElementNotNull(array[i], i);
    }
    return array;
  }

  // We do this instead of Preconditions.checkNotNull to save boxing and array
  // creation cost.
  static Object checkElementNotNull(Object element, int index) {
    if (element == null) {
      throw new NullPointerException("at index " + index);
    }
    return element;
  }
  • 雖然不能寫,但是也就不能完全實現線程安全,畢竟 sort 方法還不是安全的。

=== 點擊查看top目錄 ===

八、LinkedList 類

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
  • 注意:這個類就不實現 RandomAccess 隨機存儲結構,而是

在這裏插入圖片描述

8.1 變量

變量名 備註
transient Node last; 元素數組
transient Node first; 元素數組
transient int size = 0 數組長度
  • 注意:變量都是 transient

=== 點擊查看top目錄 ===

8.2 方法 (public)

8.2.1 插入 add
方法名 備註
public boolean add(E e) 往最後面插入
public void add(int index, E element) 在某個 index 後插入 element
public void addFirst(E e) 往最前面插入
public void addLast(E e) 往最後面插入
public boolean addAll(Collection<? extends E> c) 插入某個Collection
public boolean addAll(int index, Collection<? extends E> c) 在固定 index 後面插入某個Collection
public boolean offer(E e) 往最後面插入
public boolean offerFirst(E e) 往最前面插入
public boolean offerLast(E e) 往最後面插入
public void push(E e) 往最前面插入addFirst(e);
  • add = offer 插最後 ,push 插開頭

=== 點擊查看top目錄 ===

8.2.2 刪除 remove
方法名 備註
public E removeFirst() 摘掉第一個
public E removeLast() 摘掉最後一個
public E remove(int index) 移除掉某個 index 下的element
public boolean remove(Object o) 移除掉某個元素
public E remove() 拉出第一個元素(要remove,遇 null 拋Exception)
public boolean removeFirstOccurrence(Object o) remove(o);
public boolean removeLastOccurrence(Object o) 從後往前面刪
public E poll() 拉出第一個元素(要remove,遇 null 返回 null)
public E pollFirst() 拉出第一個元素(要remove,遇 null 返回 null)
public E pollLast() 拉出最後一個元素(要remove,遇 null 返回 null)
public E pop() pop出第一個元素(要remove,遇 null 拋Exception) removeFirst();
  1. remove = pop 遇 null 拋出 Exception
  2. poll 遇 null 返回 null

=== 點擊查看top目錄 ===

8.2.3 設置 set
方法名 備註
public E set(int index, E element) 設置 index 下面的 Element

=== 點擊查看top目錄 ===

8.2.4 get 查詢
方法名 備註
public E get(int index) 獲取某個 index 下的 Element
public E getFirst() 拿到第一個Element
public E getLast() 拿到最後一個 Element
public E element() 拿到第一個元素 (不remove,遇 null 拋Exception)
public E peek() 拿到第一個元素(不remove,遇 null 返回 null)
public E peekFirst() 拿到第一個元素(不remove,遇 null 返回 null)
public E peekLast() 拿到最後一個元素(不remove,遇 null 返回 null)

=== 點擊查看top目錄 ===

8.2.5 其他操作
方法名 備註
public int indexOf(Object o) 查找某個元素存在的下標,找不到返回 -1
public int lastIndexOf(Object o) 查找某個元素存在的下標(從後面開始找),找不到返回 -1
public boolean contains(Object o) 是否包含某個 Element
public int size() collection 長度
public void clear() 清除元素
public ListIterator listIterator(int index) 拿到 ListItr
public Iterator descendingIterator() 拿到從後往前的 Iterator
public Object clone() 克隆,淺複製 shallow copy
public Object[] toArray() 轉成數組
public Spliterator spliterator() 拿到從前往後的 Iterator

=== 點擊查看top目錄 ===


九、番外篇

下一章節:【Java Collection】Queue 剖析(四)

上一章節:【Java Collection】List 剖析(二)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章