1. 概述

在本教程中,我们将讨论如何在 Java 中实现一个字符(char)类型的栈。我们会先介绍使用 Java 内置 API 的方式,然后再看看几种自定义实现的方法。

栈(Stack)是一种遵循 LIFO(Last In First Out,后进先出)原则的数据结构。常见的操作包括:

  • push(E item):将元素压入栈顶
  • pop():移除并返回栈顶元素
  • peek():仅返回栈顶元素,不移除

2. 使用 Java API 实现 Char 栈

Java 提供了内置的 java.util.Stack 类。但要注意的是,**char 是基本数据类型,不能直接用于泛型**,所以我们要使用其包装类 Character 来创建栈:

Stack<Character> charStack = new Stack<>();

这样就可以使用 pushpoppeek 方法操作栈了。

不过在实际开发中,我们有时也需要自定义栈的实现方式。接下来我们看看几种常见的自定义实现。

3. 基于 LinkedList 的自定义实现

我们可以使用 LinkedList 作为底层数据结构来实现一个 char 栈:

public class CharStack {

    private LinkedList<Character> items;

    public CharStack() {
        this.items = new LinkedList<Character>();
    }
}

我们在构造函数中初始化了 items 变量。

接着,我们实现 pushpeekpop 方法:

public void push(Character item) {
    items.push(item);
}

public Character peek() {
    return items.getFirst();
}

public Character pop() {
    Iterator<Character> iter = items.iterator();
    Character item = iter.next();
    if (item != null) {
        iter.remove();
        return item;
    }
    return null;
}

pushpeek 方法直接使用了 LinkedList 内置的方法。
⚠️ 对于 pop,我们使用了 Iterator 来判断栈顶是否有元素,有的话就调用 remove() 删除它。

4. 基于数组的自定义实现

我们也可以使用数组来实现一个 char 栈:

public class CharStackWithArray {

    private char[] elements;
    private int size;

    public CharStackWithArray() {
        size = 0;
        elements = new char[4];
    }

}

上面我们初始化了一个容量为 4 的 char 数组,并使用 size 记录当前栈中的元素个数。

实现 push 方法

public void push(char item) {
    ensureCapacity(size + 1);
    elements[size] = item;
    size++;
}

private void ensureCapacity(int newSize) {
    char newBiggerArray[];
    if (elements.length < newSize) {
        newBiggerArray = new char[elements.length * 2];
        System.arraycopy(elements, 0, newBiggerArray, 0, size);
        elements = newBiggerArray;
    }
}

push 时,我们先调用 ensureCapacity 方法确保数组容量足够。如果不够,就创建一个容量翻倍的新数组,并将原数组内容拷贝过去。

⚠️ 为什么是容量翻倍而不是只加 1?原因可以参考 StackOverflow 的这个讨论

实现 peek 和 pop 方法

public char peek() {
    if (size == 0) {
        throw new EmptyStackException();
    }
    return elements[size - 1];
}

public char pop() {
    if (size == 0) {
        throw new EmptyStackException();
    }
    return elements[--size];
}

✅ 在 peekpop 中,我们都检查了栈是否为空。
pop 方法不仅返回栈顶元素,还会将 size 减一,达到“移除”的效果。

5. 总结

本文介绍了如何使用 Java 内置 API 实现一个 char 栈,并给出了两种自定义实现方式:

  • 基于 LinkedList 的实现:简单粗暴,适合快速开发
  • 基于数组的实现:性能更可控,适合对性能有要求的场景

如果你对栈的性能、内存占用等有更高要求,可以根据实际场景选择合适的实现方式。


原始标题:Defining a Char Stack in Java | Baeldung