设计背景
计算机中很多场景会遇到“后存入的元素先被调用”(LIFO)的情况,例如编辑器的撤销操作、系统的递归调用操作。数组(Array)作为一种线性表,它可以在任意位置插入元素和取出元素,如果将数组限制为只能在尾部插入和取出元素,那么就实现了这种需求。这种数据结构被称之为栈(Stack)。
结构分析
【结构类型】线性结构
【底层实现】动态数组(ArrayList) / 链表(LinkedList)
【核心方法】
public void push(E e); //入栈
public void pop(); //出栈
public E peek(); //获取栈顶的元素
【差异分析】动态数组(ArrayList)和链表(LinkedList)都可以作为栈(Stack)的底层结构。在数值量不大的情况下,ArrayListStack的速度可能稍慢于LinkedListStack,因为ArrayList会面临频繁的扩容和缩容操作;但在数值量较大的情况下,LinkedListStack可能会耗用更长的时间,这是因为LinkedList虽不受容量约束,但其不断进行着new节点的操作;这些差异还将将取决于JVM等客观因素。
代码实现
1. 利用ArrayList实现
public class ArrayStack<E> implements Stack<E> {
/**
* 实例域:动态数组
*/
private ArrayList<E> array;
/**
* 带参构造器:对实例域进行初始化
* @param capacity 数组容量
*/
public ArrayStack(int capacity) {
array = new ArrayList<>(capacity);
}
/**
* 无参构造器:对实例域进行初始化
*/
public ArrayStack() {
array = new ArrayList<>();
}
@Override
public void push(E e) {
array.addLast(e);
}
@Override
public E pop() {
return array.removeLast();
}
@Override
public E peek() {
return array.get(getSize() - 1);
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public int getSize() {
return array.getSize();
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Stack: ");
res.append('[');
for (int i = 0; i < array.getSize(); i++) {
res.append(array.get(i));
if (i != array.getSize() - 1) {
res.append(", ");
}
}
res.append("] top");
return res.toString();
}
}
2. 利用LinkedList实现
public class LinkedListStack<E> implements Stack<E> {
/**
* 实例域:链表
*/
LinkedList<E> linkedList;
/**
* 无参构造器:利用默认值初始化实例域
*/
public LinkedListStack() {
linkedList = new LinkedList<>();
}
@Override
public void push(E e) {
linkedList.addFirst(e);
}
@Override
public E pop() {
return linkedList.removeFirst();
}
@Override
public E peek() {
return linkedList.getFirst();
}
@Override
public boolean isEmpty() {
return linkedList.isEmpty();
}
@Override
public int getSize() {
return linkedList.getSize();
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Stack: ");
res.append("top [");
res.append(linkedList);
res.append("]");
return res.toString();
}
}