当前位置:首页 > 后端开发 > 正文

Java如何手写自定义栈实战?

Java中实现自定义栈可通过数组或链表结构,核心步骤包括定义栈类、内部存储数组或链表、栈顶指针,以及实现push、pop、peek和isEmpty等方法,数组实现需处理扩容,链表实现更灵活但需管理节点。

在Java中实现自定义栈是理解数据结构基础的重要实践,栈遵循后进先出(LIFO)原则,核心操作包括入栈(push)、出栈(pop)、查看栈顶(peek)等,下面通过两种典型实现——数组链表,详细讲解开发步骤,代码可直接用于实际项目。


数组实现(固定容量)

数组实现适合预先知道栈最大深度的场景,内存连续、访问高效。

类结构与成员变量

public class ArrayStack { private int maxSize; // 栈的最大容量 private int[] stack; // 用数组存储元素 private int top; // 栈顶指针(索引) }

构造方法

初始化数组并置空栈:

Java如何手写自定义栈实战? 第1张

核心方法实现

入栈 (push)

public void push(int value) { if (isFull()) { throw new RuntimeException("栈已满!"); } stack[++top] = value; // 指针上移后写入数据 }

出栈 (pop)

public int pop() { if (isEmpty()) { throw new RuntimeException("栈为空!"); } return stack[top--]; // 返回栈顶元素,指针下移 }

查看栈顶 (peek)

Java如何手写自定义栈实战? 第2张

判空 & 判满

public boolean isEmpty() { return top == -1; } public boolean isFull() { return top == maxSize - 1; }


链表实现(动态扩容)

链表实现无需预设容量,动态扩展内存,避免空间浪费。

节点类定义

private class Node { int value; Node next; Node(int value) { this.value = value; } }

栈类与构造方法

public class LinkedStack { private Node top; // 栈顶节点 public LinkedStack() { top = null; // 初始空栈 } }

核心方法实现

入栈 (push)

Java如何手写自定义栈实战? 第3张

public void push(int value) { Node newNode = new Node(value); newNode.next = top; // 新节点指向原栈顶 top = newNode; // 更新栈顶指针 }

出栈 (pop)

public int pop() { if (isEmpty()) { throw new RuntimeException("栈为空!"); } int value = top.value; top = top.next; // 栈顶下移 return value; }

查看栈顶 (peek)

public int peek() { if (isEmpty()) { throw new RuntimeException("栈为空!"); } return top.value; }

判空

public boolean isEmpty() { return top == null; }


两种实现的对比

特性 数组实现 链表实现
容量 固定大小(需预设) 动态扩展(无上限)
内存效率 连续内存,无额外指针开销 每个节点含指针,略占空间
时间复杂度 所有操作 O(1) 所有操作 O(1)
适用场景 明确最大深度的场景(如递归解析) 频繁增减元素的动态场景


关键注意事项

  1. 异常处理

    执行pop()或peek()前必须检查空栈,避免NullPointerException。

  2. 泛型扩展

    可将int替换为泛型<T>,支持多种数据类型(如Stack<String>)。

  3. 线程安全

    多线程环境下需用synchronized修饰方法或改用ConcurrentLinkedDeque。

引用说明:本文代码基于《数据结构与算法分析(Java描述)》的栈实现逻辑,结合Oracle官方文档的异常处理规范编写,链表实现参考了Java标准库中LinkedList的链式结构思想。

0