點擊查看 Java 集合框架深刻理解 系列, - ( ゜- ゜)つロ 乾杯~html
今天心情不錯,再來一篇 Stack !java
數據結構中的 棧
數據結構中,棧是一種線性數據結構,聽從 LIFO(後進先出)的操做順序,全部操做都是在頂部進行api
有點像羽毛球筒:數組
棧一般有三種操做:markdown
push 入棧
pop 棧頂元素出棧,並返回
peek 獲取棧頂元素,並不刪除數據結構
咱們自定義一個 棧 時只要實現上述三個主要操做便可,本文中將使用 Java 中的 LinkedList 實現一個棧。
棧的使用場景:
棧最主要的意義就在於:入棧和出棧的對稱性。
在 Android 開發中,咱們常常須要開啓、回退一個 Activity,其實這裏就有棧的應用,每次開啓Activity,若是不是特殊的啓動模式,就會在棧頂加入一個 Activity,點擊返回後,以前的 Activity 出棧 。
其餘場景好比遞歸(斐波那契數列,漢諾塔)。oracle
Java 集合框架中的棧 Stack框架
Java 集合框架中的 Stack 繼承自 Vector:ide
因爲 Vector 有 4 個構造函數,加上 Stack 自己的一種,也就是說有 5 中建立 Stack 的方法
跟 Vector 同樣,它是 數組實現的棧。函數
Stack 的方法
Stack 中新建的方法比較少:
1.構造函數
//構建一個空棧
public Stack() {
}
2.入棧
//調用的 Vector.addElement()
public E push(E item) {
addElement(item);
return item;
}
Vector 的 addElement() 方法,就是在數組尾部添加元素:
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
3.獲取頂端元素,但不刪除
public synchronized E peek() {
//調用 Vector.size() 返回元素個數
int len = size();
if (len == 0) throw new EmptyStackException(); //調用 Vector.elementAt 獲得棧頂元素 return elementAt(len - 1);
}
Vector.elementAt(int):
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
Vector.elementData(int):
E elementData(int index) {
return (E) elementData[index];
}
4.出棧
public synchronized E pop() {
E obj;
int len = size();
//調用 peek() 獲取頂端元素,一下子返回 obj = peek(); //調用 Vector.removeElementAt 刪除頂端元素 removeElementAt(len - 1); return obj;
}
Vector.removeElementAt(int):
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1; if (j > 0) { System.arraycopy(elementData, index + 1, elementData, index, j); } elementCount--; elementData[elementCount] = null; /* to let gc do its work */
}
5.查找元素是否在棧中
public synchronized int search(Object o) {
int i = lastIndexOf(o);
//返回的是棧頂到該元素出現的位置的距離 if (i >= 0) { return size() - i; } return -1;
}
6.是否爲空
public boolean empty() {
return size() == 0;
}
Vector.size():
public synchronized int size() {
return elementCount;
}
總結
Java 集合框架中的 Stack 具備如下特色:
繼承自 Vector
有 5 種建立 Stack 的方法
採用數組實現
除了 push(),剩下的方法都是同步的
用鏈表實現一個棧?
因爲 Stack 是用數組實現的,咱們用鏈表實現一下吧,這裏就選擇 LinkedList 來實現:
/**
data: 10/23/2016
*/
public class LinkedListStack extends LinkedList{
public LinkedListStack(){
super();
}
@Override
public void push(Object o) {
super.push(o);
}
@Override
public Object pop() {
return super.pop();
}
@Override
public Object peek() {
return super.peek();
}
@Override
public boolean isEmpty() {
return super.isEmpty();
}
public int search(Object o){
return indexOf(o);br/>}
}
調用:
@Test
public void testPush() throws Exception {
LinkedListStack stack = new LinkedListStack();
System.out.println("棧是否爲空: " + stack.isEmpty());
stack.push("shixin");
stack.push("好帥");
stack.push("技巧一流");
stack.push("haha");
System.out.println("棧中元素: " + stack);
System.out.println("獲取頂端元素 peek :" + stack.peek());
System.out.println("頂端元素出棧 pop :" + stack.pop());
System.out.println("出棧後棧內元素:" + stack);
System.out.println("search(好帥) 的位置:" + stack.search("好帥"));
}
}
結果:
能夠看到,我其實都沒作什麼哈哈,都是 LinkedList 內部提供的方法,操做的都是在鏈表頭部的元素,而不是尾部。
其實 LinkedList 這個棧的特性也是繼承自 雙端隊列 Deque,官方也推薦在使用棧時優先使用 Deque,而不是 Stack,有興趣的能夠去了解下。
Thanks
https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html
http://www.cnblogs.com/kaituorensheng/archive/2013/03/02/2939690.html
http://www.nowamagic.net/librarys/veda/detail/2298