首页 归档 关于 learn love 工具

java手写栈

起因

在java官方文档种,有提示 Staying Away from the Stack Class , 原因是Stack 类继承 Vector ,但是Vector 类的设计和实现有缺陷,Vector是在java 1.0中开始出现,在java 1.2 版本后,新的collection框架中的List已经是官方推荐的Vector的替代品,而Vector仅仅是作为向后兼容使用。
不推荐使用Vector的的原因如下,原文

  • 性能问题,Vector的所有方法都使用了 synchronization ,也就是加锁了
  • Vector只是对方法进行加锁,对整个类没有加锁,也就是不同线程,可以同时调用同一实例不同的方法

官方替代品

推荐用ArrayList 替代 Vector, Deque 替代 Stack

手写Stack

  1. 先定义Stack接口
/**
 * A small stack interface. You can (1) query the size of the stack, (2) ask
 * whether it is empty, (3) push an item, (4) pop an item, and (5) peek at the
 * top item.
 */
public interface Stack {

    /**
     * Adds the given item to the top of the stack.
     */
    void push(Object item);

    /**
     * Removes the top item from the stack and returns it.
     * 
     * @exception java.util.NoSuchElementException if the stack is empty.
     */
    Object pop();

    /**
     * Returns the top item from the stack without popping it.
     * 
     * @exception java.util.NoSuchElementException if the stack is empty.
     */
    Object peek();

    /**
     * Returns the number of items currently in the stack.
     */
    int size();

    /**
     * Returns whether the stack is empty or not.
     */
    default boolean isEmpty() {
        return size() == 0;
    }
}
  1. A Linked Stack ,基于 link 实现
import java.util.NoSuchElementException;

/**
 * An implementation of the stack interface using singly-linked nodes.
 */
public class LinkedStack implements Stack {
    private record Node(Object data, Node next) {
    }

    private Node top = null;
    private int size = 0;

    public void push(Object item) {
        top = new Node(item, top);
        size++;
    }

    public Object pop() {
        var item = peek();
        top = top.next;
        size--;
        return item;
    }

    @Override
    public boolean isEmpty() {
        // Override the default implementation for efficiency
        return top == null;
    }

    public Object peek() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return top.data;
    }

    public int size() {
        return size;
    }
}

利用stack解决括号匹配问题

public class ValidBracketChecker {

    public static boolean validBrackets(String s) {
        var stack = new LinkedStack();
        try {
            for (var c : s.toCharArray()) {
                if (c == '(' || c == '[' || c == '{') {
                    stack.push(String.valueOf(c));
                } else if (c == '}' && !stack.pop().equals("{")) {
                    return false;
                } else if (c == ']' && !stack.pop().equals("[")) {
                    return false;
                } else if (c == ')' && !stack.pop().equals("(")) {
                    return false;
                }
            }
            // If there is anything left over on the stack after running
            // through the whole string, we have "unclosed" brackets
            return stack.isEmpty();
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        System.out.println(validBrackets(args[0]));
    }
}

参考

https://cs.lmu.edu/~ray/notes/stacks/