Stack源码详解(基于jdk1.8.0_261)
1. Stack简介
- Stack继承了Vector类,故也是线程安全的;
- 栈是一种后进先出的数据结构;
- 不推荐使用,因为Stack继承自Vector,但是二者直接并无"is - a" 关系,且Stack可以调用Vector中的大量方法,程序员可能为了方便大量调用这些方法,产生混乱,Stack底层还是数组,需要扩容,效率底下,总之,不伦不类。
- 建议使用Deque
stack = new ArrayDeque ()来封装模拟栈;
2. Stack UML简图
3. API概述
public E push(E item) //入栈
public synchronized E pop() //出栈
public synchronized E peek() //查看栈顶
public boolean empty() //判空
public synchronized int search(Object o) //查找元素位置(从栈顶找到栈底,其中栈顶的元素索引最大,栈顶到栈底索引是递减的)
不谈直接继承自Vector类的方法,那没有意义,使用那些方法是极为糟糕的!
4. Stack源码简介
package java.util;
public class Stack<E> extends Vector<E> {
//创建一个空栈
public Stack() {
}
// 将item压入栈顶
public E push(E item) {
addElement(item);
return item;
}
//将栈顶的元素弹出,返回栈顶元素
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
//返回栈顶元素,不弹出
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
//检查栈是否为空,为空返回true
public boolean empty() {
return size() == 0;
}
//查找对象o在栈中的位置
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
private static final long serialVersionUID = 1224463164541339165L;
}
5. Stack使用示例
public class StackTest {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
System.out.println(stack.peek());
System.out.println(stack);
System.out.println(stack.pop());
System.out.println(stack);
}
}
6. 面试session
- 谈谈对Stack类的认识吧?
Stack是一种LIFO的数据结构,继承自Vector类,故也是线程安全的,涉及于JDK1.0,设计的是十分糟糕,不建议使用了。原因如下:
- 可以直接使用继承自Vector中其他方法,那就完全失去了Stack作为栈的初衷;
- 底层的数据结构还是数组,单线程中的扩容机制,锁机制使得效率十分低下;
如果还要使用,在单线程中建议利用LinkedList模拟栈。
- 在多线程中,也不想使用Stack,有什么替代stack类的方案吗?
~未完成