Understanding the JDK Stack Implementation and Its Practical Applications
This article explains the meaning of "stack" in Java, examines the JDK's Stack class implementation—including its inheritance from Vector and core methods—provides full source code, demonstrates array manipulation with System.arraycopy, and explores common stack applications such as browser navigation, function call stacks, and complexity analysis.
The article begins by clarifying the term Stack in Chinese, distinguishing it from Heap , and noting that "Stack" is often abbreviated as 栈.
It then introduces the JDK's official stack implementation, showing that the class Stack extends Vector . The inheritance diagram is described, and the most important methods— push , pop , and peek —are listed.
The full source code of the JDK Stack class is presented:
public class Stack
extends Vector
{
/** 创建一个空栈 */
public Stack() {}
/** 入栈方法,调用 Vector#addElement */
public E push(E item) {
addElement(item);
return item;
}
/** 出栈并返回当前元素,调用 Vector#removeElementAt */
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
/** 查询栈顶元素,调用 Vector#elementAt */
public synchronized E peek() {
int len = size();
if (len == 0) throw new EmptyStackException();
return elementAt(len - 1);
}
/** 判断栈是否为空 */
public boolean empty() {
return size() == 0;
}
// ... other methods omitted
}From this code it is evident that all core stack operations delegate to the parent Vector class. The article therefore shows the essential parts of the Vector source:
public class Vector
extends AbstractList
implements List
, RandomAccess, Cloneable, java.io.Serializable {
protected Object[] elementData; // storage array
protected int elementCount; // number of elements
/** 添加数据 */
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
/** 移除元素(根据下标) */
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
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;
}
/** 查询元素(根据下标) */
public synchronized E elementAt(int index) {
if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
return (E) elementData[index];
}
// ... other methods omitted
}The article highlights the often‑confusing System.arraycopy call used when removing a non‑last element, and provides a concrete example:
Object[] elementData = {"Java", "Hello", "world", "JDK", "JRE"};
int index = 3;
int j = elementData.length - index - 1;
System.arraycopy(elementData, index + 1, elementData, index, j);
System.out.println(Arrays.toString(elementData));The output demonstrates how the element at index 3 is overwritten, resulting in [Java, Hello, world, JRE, JRE] , after which the duplicate tail element can be discarded.
Beyond the implementation details, the article discusses practical stack applications:
Browser back‑navigation, which relies on the LIFO property of a stack.
The function‑call stack, illustrated with a simple Java program and a diagram showing how method frames are pushed and popped.
It also examines the time and space complexity of stack operations, noting that typical push/pop are O(1) while traversals are O(n). Simple code snippets illustrate O(n) and O(1) examples.
Finally, the article provides a summary stating that the JDK Stack is built on an array‑based Vector , and links to related articles for deeper study.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.