stack被称为“栈”,其特点是“先进后出”。是线性的顺序~~~我们今天来看一下Stack的源码~
stack继承于vector,所以stack的存储结构也是数组实现的了,而vector我们在上一节已经将过了~~~
同时,stack中的每个方法都由synchronized关键字修饰,所以stack在多线程环境下也是线程安全的。
首先,创建stack对象的方式如下
Stack<String> s1=new Stack<String>();
我们接下来对stack中的方法进行源码剖析~~
push()方法是“入栈”的意思,将元素添加到栈内,源码如下:
public E push(E item) { addElement(item); return item; }
我们可以看出,stack.push()其实事利用vector中的addElement()实现的。
peek()该方法事取出 栈顶元素,该方法只是单纯的取出栈顶元素,但是不改变栈。源码如下:
public synchronized E peek() { int len = size(); if (len == 0) throw new EmptyStackException(); return elementAt(len - 1); }
public synchronized E elementAt(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } return elementData(index); }
E elementData(int index) { return (E) elementData[index]; }
我们可以看到,peek()方法内部调用了vector内部的elementAt()方法来获取栈顶元素。
pop()方法“出栈”的意思,依次从栈顶到栈底。但是和peek()不一样的是,pop()改变了栈内部的数据,我们来看一下源代码:
public synchronized E pop() { E obj; int len = size(); obj = peek(); removeElementAt(len - 1); return obj; }
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 */ }
我们可以看出,pop()源代码中首先通过peek()方法取出栈顶元素,然后,再调用vector中的removeElementAt()方法删除栈顶元素。
当然,栈的长度增长规则也和vector一样了~~~每次增长原来的一倍!!
ok~~stack就到这了~~大家有时间去研究以下源码把~~
寂寞的人总是记住生命中出现的每一个人,