1. 程式人生 > 其它 >007Java集合003詳解Vector、Stack

007Java集合003詳解Vector、Stack

本文主要學習了Vector和Stack,包括擴容機制和常用的屬性方法。

注意:本文基於JDK1.8進行記錄。

1 Vector

1.1 簡介

不常用的集合,和ArrayList類似,允許任何符合規則的元素插入,包括null和重複元素。

底層是陣列結構,提供了索引機制,查詢效率高,增刪效率低。

執行緒安全,使用了synchronized關鍵字。

1.2 擴容機制

擴容機制和ArrayList類似,初始容量預設為10,負載因子是1,表示當插入元素後個數超出原有長度時會進行擴增,擴容增量是預設為原容量,所以擴增後容量為2倍,可使用方法手動擴容和縮減。

最好指定初始容量值和增量,避免過多的進行擴容操作而浪費時間和效率。

1.3 方法說明

1.3.1 構造方法

1 // 空參構造器,返回預設容量為10的集合。
2 public Vector(); 3 // 指定長度的構造器,預設增量為0。 4 public Vector(int initialCapacity); 5 // 指定長度和增量的構造器,預設增量為0。 6 public Vector(int initialCapacity, int capacityIncrement); 7 // 傳入了一個集合的構造器,如果集合長度為0,返回容量為0的集合。 8 public Vector(Collection<? extends E> c);

1.3.2 常用方法

 1 // 獲取指定下標的元素。
 2 public synchronized E get(int
index); 3 // 設定指定下標的指定元素,並返回舊元素。 4 public synchronized E set(int index, E element); 5 // 新增元素,並返回是否成功。 6 public synchronized boolean add(E e); 7 // 在指定位置新增指定元素。 8 public void add(int index, E element); 9 // 刪除指定位置的元素,並返回刪除的元素。 10 public synchronized E remove(int index); 11 // 刪除元素,並返回是否成功。 12 public boolean
remove(Object o);

1.4 原始碼分析

1.4.1 屬性

1 // 陣列。
2 protected Object[] elementData;
3 // 元素個數。
4 protected int elementCount;
5 // 擴容增量
6 protected int capacityIncrement;

1.4.2 構造方法

 1 // 空參構造器,返回預設容量為10的集合。
 2 public Vector() {
 3     this(10);
 4 }
 5 // 指定長度的構造器,預設增量為0。
 6 public Vector(int initialCapacity) {
 7     this(initialCapacity, 0);
 8 }
 9 // 指定長度和增量的構造器,預設增量為0。
10 public Vector(int initialCapacity, int capacityIncrement) {
11     super();
12     if (initialCapacity < 0)
13         throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
14     this.elementData = new Object[initialCapacity];
15     this.capacityIncrement = capacityIncrement;
16 }
17 // 傳入了一個集合的構造器,如果集合長度為0,返回容量為0的集合。
18 public Vector(Collection<? extends E> c) {
19     elementData = c.toArray();
20     elementCount = elementData.length;
21     // Object[]數組裡的型別不一定都是Object型別的,有可能是Object的子類,所以要判斷一下。
22     if (elementData.getClass() != Object[].class)
23         elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
24 }

1.4.3 常用方法

 1 // 獲取指定下標的元素。
 2 public synchronized E get(int index) {
 3     // 檢查指定下標是否越界。
 4     if (index >= elementCount)
 5         throw new ArrayIndexOutOfBoundsException(index);
 6     // 返回指定下標的元素。
 7     return elementData(index);
 8 }
 9 // 設定指定下標的指定元素,並返回舊元素。
10 public synchronized E set(int index, E element) {
11     // 檢查指定下標是否越界。
12     if (index >= elementCount)
13         throw new ArrayIndexOutOfBoundsException(index);
14     // 設定指定元素並返回舊元素。
15     E oldValue = elementData(index);
16     elementData[index] = element;
17     return oldValue;
18 }
19 // 新增元素,並返回是否成功。
20 public synchronized boolean add(E e) {
21     // 運算元自增。
22     modCount++;
23     // 擴容。
24     ensureCapacityHelper(elementCount + 1);
25     // 元素個數增加並設定指定元素。
26     elementData[elementCount++] = e;
27     // 返回成功。
28     return true;
29 }
30 // 在指定位置新增指定元素。
31 public void add(int index, E element) {
32     insertElementAt(element, index);
33 }
34 // 刪除指定位置的元素,並返回刪除的元素。
35 public synchronized E remove(int index) {
36     // 運算元自增。
37     modCount++;
38     // 檢查指定下標是否越界。
39     if (index >= elementCount)
40         throw new ArrayIndexOutOfBoundsException(index);
41     // 獲取指定下標的元素。
42     E oldValue = elementData(index);
43     // 需要移動的元素個數。
44     int numMoved = elementCount - index - 1;
45     if (numMoved > 0)
46         System.arraycopy(elementData, index+1, elementData, index, numMoved);
47     // 將最後一個元素設定為null並減少容量大小。
48     elementData[--elementCount] = null;
49     // 返回指定下標的元素。
50     return oldValue;
51 }
52 // 刪除元素,並返回是否成功。
53 public boolean remove(Object o) {
54     return removeElement(o);
55 }

1.4.4 擴容方法

 1 // 對集合進行擴容。
 2 public synchronized void ensureCapacity(int minCapacity) {
 3     // 如果指定容量大於擴充值,則進行擴容。
 4     if (minCapacity > 0) {
 5         // 運算元自增。
 6         modCount++;
 7         ensureCapacityHelper(minCapacity);
 8     }
 9 }
10 // 對集合進行擴容。
11 private void ensureCapacityHelper(int minCapacity) {
12     // 如果最小值大於陣列長度,則進行擴容。
13     if (minCapacity - elementData.length > 0)
14         grow(minCapacity);
15 }
16 // 陣列作為一個物件,需要一定的記憶體儲存物件頭資訊,物件頭資訊最大佔用記憶體不可超過8位元組。
17 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
18 // 擴容計算。
19 private void grow(int minCapacity) {
20     // 獲取原容量大小。
21     int oldCapacity = elementData.length;
22     // 如果增量大於0,則使用增量,否則使用原容量作為增量,最後加上原容量作為新容量。
23     int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
24     // 如果擴容後小於最小值,則設定容量為最小值。
25     if (newCapacity - minCapacity < 0)
26         newCapacity = minCapacity;
27     // 如果擴容後大於最大值,則進一步設定容量。
28     if (newCapacity - MAX_ARRAY_SIZE > 0)
29         newCapacity = hugeCapacity(minCapacity);
30     // 複製陣列。
31     elementData = Arrays.copyOf(elementData, newCapacity);
32 }
33 // 擴容後容量過大的處理方法。
34 private static int hugeCapacity(int minCapacity) {
35     // 如果最小值小於零,則表示溢位,丟擲記憶體溢位異常。
36     if (minCapacity < 0)
37         throw new OutOfMemoryError();
38     // 如果擴容後的值大於最大值,則使用Integer的最大值,否則就使用最大值。
39     return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
40 }

2 Stack

2.1 簡介

不常用的集合,繼承自Vector,允許任何符合規則的元素插入,包括null和重複元素。

同Vector類似,底層是陣列結構,但通過對Vector的擴充套件,將陣列結構倒置形成堆疊結構,使用典型的後進先出操作方式。

執行緒安全,使用了synchronized關鍵字。

2.2 擴容機制

同Vector。

2.3 方法說明

2.3.1 構造方法

1 public Stack();

2.3.2 常用方法

 1 // 判斷是否為空。
 2 public boolean empty();
 3 // 入棧,新增到棧頂。
 4 public E push(E item);
 5 // 出棧,檢視並刪除棧頂元素。
 6 public synchronized E pop();
 7 // 檢視棧頂元素。
 8 public synchronized E peek();
 9 // 查詢元素,返回棧中首次出現下標。
10 public synchronized int search(Object o);

2.4 原始碼分析

2.4.1 構造方法

1 public Stack() {
2 }

2.4.2 常用方法

 1 // 判斷是否為空。
 2 public boolean empty() {
 3     // 通過Vector的size()方法判斷。
 4     return size() == 0;
 5 }
 6 // 入棧,新增到棧頂。
 7 public E push(E item) {
 8     // 實際新增到陣列尾部。
 9     addElement(item);
10     return item;
11 }
12 // 出棧,檢視並刪除棧頂元素。
13 public synchronized E pop() {
14     E       obj;
15     int     len = size();
16     // 實際檢視陣列尾部元素。
17     obj = peek();
18     // 實際刪除陣列尾部元素。
19     removeElementAt(len - 1);
20     return obj;
21 }
22 // 檢視棧頂元素。
23 public synchronized E peek() {
24     int     len = size();
25     if (len == 0)
26         throw new EmptyStackException();
27     // 實際檢視陣列尾部元素。
28     return elementAt(len - 1);
29 }
30 // 查詢元素,返回棧中首次出現下標。
31 public synchronized int search(Object o) {
32     // 實際檢視元素在陣列最後出現位置。
33     int i = lastIndexOf(o);
34     if (i >= 0) {
35         // 轉換為棧中位置。
36         return size() - i;
37     }
38     return -1;
39 }