1.Stack的基本介绍java
Stack是一种后进先出(LIFO)的结构,其继承了Vector的基础上拓展5个方法push()、pop()、peek()、empty()、search()而来数组
a、push(E):将item推入到栈中,依次加入数组中(数组尾部)。安全
b、pop() :将栈中的最顶一个(数组尾部)item推出,并返回被推出的item数据结构
e、peek():返回栈中最顶(数组尾部)的一个item,但不对其作任何操做函数
d、empty():判断该栈是否为空this
e、search(Object):搜索某一个item在该栈中的位置【位置为离栈顶最近的item与栈顶间距离】线程
PS:虽然Java有提供该类型的数据结构,可是官方推荐使用Deque【双端队列】,Deque提供更好的完整性和一致性,应该优先使用。code
Stack基于Vector(Vector的方法用Synchronized修饰的),另外Stack中的pop、peek、search方法夜都是用Synchronized修饰的,因此Stack是线程安全的。对象
2.Stack的类结构继承
public class Stack<E> extends Vector<E> { ...... }
3.Stack的成员变量
Stack自己类中没有成员变量,可是由于Stack继承了Vector类,因此我们得看下Vector的成员变量。
//存储数据的数组 protected Object[] elementData; //实际存储的元素个数 protected int elementCount; //扩容的增量值 protected int capacityIncrement;
4.Stack的构造函数
Stack只有一个构造函数。
public Stack() {}
因为Stack继承了Vector,因此我们还得看下Vector的构造函数
public Vector() { //默认初始大小是10 this(10); } public Vector(int initialCapacity) { //默认增量为0 this(initialCapacity, 0); } public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; }
5.Stack的主要方法
5.1添加
public E push(T item);
public E push(E item) { //添加元素 addElement(item); //返回添加的元素 return item; } //该方法是Vector的方法 //该方法使用synchronized修饰了,因此是线程安全的 public synchronized void addElement(E obj) { //修改次数加一 modCount++; //判断是否须要扩容 ensureCapacityHelper(elementCount + 1); //将被添加的对象放置在elementCount++位置,即size+1 elementData[elementCount++] = obj; } //该方法是Vector的方法 private void ensureCapacityHelper(int minCapacity) { //判断是否须要扩容:size+1是否大于当前数组的长度 if (minCapacity - elementData.length > 0) //扩容 grow(minCapacity); } //该方法是Vector的方法 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //capacityIncrement为每次扩容的增量 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //复制到新的数组 elementData = Arrays.copyOf(elementData, newCapacity); }
经过查看源码咱们发现Stack的底层数据结构也是数组,能够动态扩容,和ArrayList的底层数据结构是同样的,可是扩容方法有区别,ArrayList通常是扩容至1.5倍,而Stack有个扩容增量值,若是该增量值大于零,新容量值就等于就容量值加上增量值,不然即为旧容量值的两倍。
5.2.public synchronized E peek();返回栈顶(数组尾部)的元素,但不将其从栈中删除。
public synchronized E peek() { //获取当前数组中元素个数 int len = size(); if (len == 0) throw new EmptyStackException(); //返回数组尾部元素,因此后进先出 return elementAt(len - 1); } //Vector中的方法 public synchronized E elementAt(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } return elementData(index); } //Vector中的方法 E elementData(int index) { return (E) elementData[index]; }
5.3.public synchronized E pop():返回栈顶(数组尾部)的元素,并将其从栈中删除。
public synchronized E pop() { E obj; int len = size(); //获取数组尾部元素 obj = peek(); //将尾部元素删除 removeElementAt(len - 1); return obj; }
5.4.public synchronized int search(Object o);
public synchronized int search(Object o) { //返回数组中最后一个元素为o的下角标 int i = lastIndexOf(o); if (i >= 0) { //返回栈顶(数组尾部)与该元素的距离 return size() - i; } return -1; }
至此,java.util.Stack的基本介绍完成!。