Stack源码解析
Stack介绍:
堆栈(Stack)是一个元素序列。盾战中唯一能被删除、访问或修改的元素是最近插入的元素。这个元素就是位于堆栈顶部的那个元素。
举例来说,自助餐厅的盘子架就是一个由盘子构成的堆栈。增加和移除操作只能在顶部进行。为了把它重新摆放,刚刚放到架子上的盘子将在下一次被移动。这种堆栈属性的定义有时简称为“后进先出”,或者LIFO。和这种观点相对应,我们把插入称为压栈(push),删除称为弹栈(pop)。为了逗以p字母开头,我们把得到栈顶元素的操作称为浏览(peek)。
public class Stack<E> extends Vector<E>;Stack类集成Vector,为了提高效率Stack对象的栈顶元素位于数组的size()-1索引位置,栈底位于索引0.Stack类的这种实现的致命缺点是:它并不禁止Vector类的任何方法,因此在一个Stack对象的任何位置插入、删除都是合法的。想象下面这种情况:在Stack类中,调用了违反堆栈定义的方法居然是合法的!您也许会说这种实现有点过了头。
Stack源码解析:
1 package list.Stack; 2 3 import java.util.EmptyStackException; 4 import java.util.Vector; 5 6 public class Stack<E> extends Vector<E> { 7 /** 8 * 创建一个新的Stack. 9 */ 10 public Stack() { 11 } 12 13 // 在栈顶,也及时数组的末尾添加元素 14 public E push(E item) { 15 addElement(item); 16 17 return item; 18 } 19 20 //删除栈顶的元素,并返回该元素 21 public synchronized E pop() { 22 E obj; 23 int len = size(); 24 obj = peek(); 25 removeElementAt(len - 1); 26 return obj; 27 } 28 29 //浏览栈顶的元素 30 public synchronized E peek() { 31 int len = size(); 32 33 if (len == 0) 34 throw new EmptyStackException(); 35 return elementAt(len - 1); 36 } 37 38 //判断堆栈中元素的数量是否为0 39 public boolean empty() { 40 return size() == 0; 41 } 42 43 //判断堆栈中是否含有某个元素 44 public synchronized int search(Object o) { 45 int i = lastIndexOf(o); 46 47 if (i >= 0) { 48 return size() - i; 49 } 50 return -1; 51 } 52 53 private static final long serialVersionUID = 1224463164541339165L; 54 }
总结:
(01) Stack实际上也是通过数组去实现的。
执行push时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。
执行peek时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。
执行pop时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。
(02) Stack继承于Vector,意味着Vector拥有的属性和功能,Stack都拥有。而且其实现压栈(push),弹栈(pop)等操作也是调用了Vector类中的方法。
Stack示例:
1 package list.vector; 2 3 import java.util.Stack; 4 5 public class VectorDemo { 6 public static void main(String[] args) { 7 Stack<String> strs = new Stack<String>(); 8 //将0~9添加到堆栈中 9 for (int i = 0; i < 10; i++) { 10 strs.push(i+""); 11 } 12 //遍历堆栈 13 //for循环快速遍历 14 for (int i = 0; i < strs.size(); i++) { 15 System.out.print(strs.get(i)); 16 } 17 System.out.println(); 18 System.out.println("------1-----" ); 19 //栈弹出遍历方式 20 // while (s.peek()!=null) { //不健壮的判断方式,容易抛异常,正确写法是下面的 21 while (!strs.empty()) { 22 System.out.print(strs.pop()); 23 } 24 System.out.println(); 25 System.out.println("------2-----" ); 26 } 27 }
运行结果:
0123456789 ------1----- 9876543210 ------2-----
写在最后:
此篇随笔仅用来记录我的学习内容,如有错误,欢迎指正。谢谢!!!