1 public 2 class Stack<E> extends Vector<E> {
咱們發現Stack繼承了Vector,Vector又是什麼東東呢,看一下。html
1 public class Vector<E> 2 extends AbstractList<E> 3 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
發現沒有,Vector是List的一個實現類,其實Vector也是一個基於數組實現的List容器,其功能及實現代碼和ArrayList基本上是同樣的。那麼不同的是什麼地方的,一個是數組擴容的時候,Vector是*2,ArrayList是*1.5+1;另外一個就是Vector是線程安全的,而ArrayList不是,而Vector線程安全的作法是在每一個方法上面加了一個synchronized關鍵字來保證的。可是這裏說一句,Vector已經不官方的(你們公認的)不被推薦使用了,正式由於其實現線程安全方式是鎖定整個方法,致使的是效率不高,那麼有沒有更好的提到方案呢,其實也不能說有,可是還真就有那麼一個,Collections.synchronizedList(),這不是咱們今天的重點不作深刻探討,回到Stack的實現上。java
1 // 底層使用數組存儲數據 2 protected Object[] elementData; 3 // 元素個數 4 protected int elementCount ; 5 // 自定義容器擴容遞增大小 6 protected int capacityIncrement ; 7 8 public Vector( int initialCapacity, int capacityIncrement) { 9 super(); 10 // 越界檢查 11 if (initialCapacity < 0) 12 throw new IllegalArgumentException( "Illegal Capacity: " + 13 initialCapacity); 14 // 初始化數組 15 this.elementData = new Object[initialCapacity]; 16 this.capacityIncrement = capacityIncrement; 17 } 18 19 // 使用synchronized關鍵字鎖定方法,保證同一時間內只有一個線程能夠操縱該方法 20 public synchronized boolean add(E e) { 21 modCount++; 22 // 擴容檢查 23 ensureCapacityHelper( elementCount + 1); 24 elementData[elementCount ++] = e; 25 return true; 26 } 27 28 private void ensureCapacityHelper(int minCapacity) { 29 // 當前元素數量 30 int oldCapacity = elementData .length; 31 // 是否須要擴容 32 if (minCapacity > oldCapacity) { 33 Object[] oldData = elementData; 34 // 若是自定義了容器擴容遞增大小,則按照capacityIncrement進行擴容,不然按兩倍進行擴容(*2) 35 int newCapacity = (capacityIncrement > 0) ? 36 (oldCapacity + capacityIncrement) : (oldCapacity * 2); 37 if (newCapacity < minCapacity) { 38 newCapacity = minCapacity; 39 } 40 // 數組copy 41 elementData = Arrays.copyOf( elementData, newCapacity); 42 } 43 }
1 /** 2 * 獲取棧頂的對象,可是不刪除 3 */ 4 public synchronized E peek() { 5 // 當前容器元素個數 6 int len = size(); 7 8 // 若是沒有元素,則直接拋出異常 9 if (len == 0) 10 throw new EmptyStackException(); 11 // 調用elementAt方法取出數組最後一個元素(最後一個元素在棧頂) 12 return elementAt(len - 1); 13 } 14 15 /** 16 * 根據index索引取出該位置的元素,這個方法在Vector中 17 */ 18 public synchronized E elementAt(int index) { 19 // 越界檢查 20 if (index >= elementCount ) { 21 throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); 22 } 23 24 // 直接經過數組下標獲取元素 25 return (E)elementData [index]; 26 }
4.pop()——彈棧(出棧),獲取棧頂的對象,並將該對象從容器中刪除數組
1 /** 2 * 彈棧,獲取並刪除棧頂的對象 3 */ 4 public synchronized E pop() { 5 // 記錄棧頂的對象 6 E obj; 7 // 當前容器元素個數 8 int len = size(); 9 10 // 經過peek()方法獲取棧頂對象 11 obj = peek(); 12 // 調用removeElement方法刪除棧頂對象 13 removeElementAt(len - 1); 14 15 // 返回棧頂對象 16 return obj; 17 } 18 19 /** 20 * 根據index索引刪除元素 21 */ 22 public synchronized void removeElementAt(int index) { 23 modCount++; 24 // 越界檢查 25 if (index >= elementCount ) { 26 throw new ArrayIndexOutOfBoundsException(index + " >= " + 27 elementCount); 28 } 29 else if (index < 0) { 30 throw new ArrayIndexOutOfBoundsException(index); 31 } 32 // 計算數組元素要移動的個數 33 int j = elementCount - index - 1; 34 if (j > 0) { 35 // 進行數組移動,中間刪除了一個,因此將後面的元素往前移動(這裏直接移動將index位置元素覆蓋掉,就至關於刪除了) 36 System. arraycopy(elementData, index + 1, elementData, index, j); 37 } 38 // 容器元素個數減1 39 elementCount--; 40 // 將容器最後一個元素置空(由於刪除了一個元素,而後index後面的元素都向前移動了,因此最後一個就沒用了 ) 41 elementData[elementCount ] = null; /* to let gc do its work */ 42 }
5.push(E item)——壓棧(入棧),將對象添加進容器並返回安全
1 /** 2 * 將對象添加進容器並返回 3 */ 4 public E push(E item) { 5 // 調用addElement將元素添加進容器 6 addElement(item); 7 // 返回該元素 8 return item; 9 } 10 11 /** 12 * 將元素添加進容器,這個方法在Vector中 13 */ 14 public synchronized void addElement(E obj) { 15 modCount++; 16 // 擴容檢查 17 ensureCapacityHelper( elementCount + 1); 18 // 將對象放入到數組中,元素個數+1 19 elementData[elementCount ++] = obj; 20 }
6.search(Object o)——返回對象在容器中的位置,棧頂爲1數據結構
1 /** 2 * 返回對象在容器中的位置,棧頂爲1 3 */ 4 public synchronized int search(Object o) { 5 // 從數組中查找元素,從最後一次出現 6 int i = lastIndexOf(o); 7 8 // 由於棧頂算1,因此要用size()-i計算 9 if (i >= 0) { 10 return size() - i; 11 } 12 return -1; 13 }
7.empty()——容器是否爲空dom
1 /** 2 * 檢查容器是否爲空 3 */ 4 public boolean empty() { 5 return size() == 0; 6 }
1 import java.util.LinkedList; 2 3 public class LinkedStack<E> { 4 5 private LinkedList<E> linked ; 6 7 public LinkedStack() { 8 this.linked = new LinkedList<E>(); 9 } 10 11 public E push(E item) { 12 this.linked .addFirst(item); 13 return item; 14 } 15 16 public E pop() { 17 if (this.linked.isEmpty()) { 18 return null; 19 } 20 return this.linked.removeFirst(); 21 } 22 23 public E peek() { 24 if (this.linked.isEmpty()) { 25 return null; 26 } 27 return this.linked.getFirst(); 28 } 29 30 public int search(E item) { 31 int i = this.linked.indexOf(item); 32 return i + 1; 33 } 34 35 public boolean empty() { 36 return this.linked.isEmpty(); 37 } 38 }