有人能给我解释一下Java中使用链表的堆栈的以下实现吗?

有人能给我解释一下Java中使用链表的堆栈的以下实现吗?,java,linked-list,stack,Java,Linked List,Stack,有人能给我解释一下Java中使用链表的堆栈的以下实现吗?链接如下:代码如下: public class LinkedStack<Item> implements Iterable<Item> { private int N; // size of the stack private Node first; // top of stack // helper linked list class pri

有人能给我解释一下Java中使用链表的堆栈的以下实现吗?链接如下:代码如下:

       public class LinkedStack<Item> implements Iterable<Item> {
    private int N;          // size of the stack
    private Node first;     // top of stack

    // helper linked list class
    private class Node {
        private Item item;
        private Node next;
    }

    /**
     * Initializes an empty stack.
     */
    public LinkedStack() {
        first = null;
        N = 0;
        assert check();
    }

    /**
     * Is this stack empty?
     * @return true if this stack is empty; false otherwise
     */
    public boolean isEmpty() {
        return first == null;
    }

    /**
     * Returns the number of items in the stack.
     * @return the number of items in the stack
     */
    public int size() {
        return N;
    }

    /**
     * Adds the item to this stack.
     * @param item the item to add
     */
    public void push(Item item) {
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        N++;
        assert check();
    }

    /**
     * Removes and returns the item most recently added to this stack.
     * @return the item most recently added
     * @throws java.util.NoSuchElementException if this stack is empty
     */
    public Item pop() {
        if (isEmpty()) throw new NoSuchElementException("Stack underflow");
        Item item = first.item;        // save item to return
        first = first.next;            // delete first node
        N--;
        assert check();
        return item;                   // return the saved item
    }


    /**
     * Returns (but does not remove) the item most recently added to this stack.
     * @return the item most recently added to this stack
     * @throws java.util.NoSuchElementException if this stack is empty
     */
    public Item peek() {
        if (isEmpty()) throw new NoSuchElementException("Stack underflow");
        return first.item;
    }

    /**
     * Returns a string representation of this stack.
     * @return the sequence of items in the stack in LIFO order, separated by spaces
     */
    public String toString() {
        StringBuilder s = new StringBuilder();
        for (Item item : this)
            s.append(item + " ");
        return s.toString();
    }

    /**
     * Returns an iterator to this stack that iterates through the items in LIFO order.
     * @return an iterator to this stack that iterates through the items in LIFO order.
     */
    public Iterator<Item> iterator()  { return new ListIterator();  }

    // an iterator, doesn't implement remove() since it's optional
    private class ListIterator implements Iterator<Item> {
        private Node current = first;
        public boolean hasNext()  { return current != null;                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next; 
            return item;
        }
    }


    // check internal invariants
    private boolean check() {
        if (N == 0) {
            if (first != null) return false;
        }
        else if (N == 1) {
            if (first == null)      return false;
            if (first.next != null) return false;
        }
        else {
            if (first.next == null) return false;
        }

        // check internal consistency of instance variable N
        int numberOfNodes = 0;
        for (Node x = first; x != null; x = x.next) {
            numberOfNodes++;
        }
        if (numberOfNodes != N) return false;

        return true;
    }

    /**
     * Unit tests the <tt>LinkedStack</tt> data type.
     */
    public static void main(String[] args) {
        LinkedStack<String> s = new LinkedStack<String>();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            if (!item.equals("-")) s.push(item);
            else if (!s.isEmpty()) StdOut.print(s.pop() + " ");
        }
        StdOut.println("(" + s.size() + " left on stack)");
    }
}
公共类LinkedStack实现Iterable{
private int N;//堆栈的大小
私有节点优先;//堆栈顶部
//助手链表类
私有类节点{
私人物品;
私有节点下一步;
}
/**
*初始化空堆栈。
*/
公共LinkedStack(){
第一个=空;
N=0;
断言检查();
}
/**
*这个堆栈是空的吗?
*@如果此堆栈为空,则返回true;否则返回false
*/
公共布尔值为空(){
返回first==null;
}
/**
*返回堆栈中的项数。
*@返回堆栈中的项目数
*/
公共整数大小(){
返回N;
}
/**
*将该项添加到此堆栈。
*@param item要添加的项
*/
公共作废推送(项目){
节点oldfirst=第一个;
第一个=新节点();
first.item=项目;
first.next=oldfirst;
N++;
断言检查();
}
/**
*删除并返回最近添加到此堆栈的项。
*@返回最近添加的项目
*如果此堆栈为空,则@throws java.util.NoSuchElementException
*/
公共物品{
如果(isEmpty())抛出新的NoTouchElementException(“堆栈下溢”);
Item=first.Item;//保存要返回的项
first=first.next;//删除第一个节点
N--;
断言检查();
return item;//返回保存的项
}
/**
*返回(但不删除)最近添加到此堆栈的项。
*@返回最近添加到此堆栈的项目
*如果此堆栈为空,则@throws java.util.NoSuchElementException
*/
公共项目peek(){
如果(isEmpty())抛出新的NoTouchElementException(“堆栈下溢”);
返回第一个项目;
}
/**
*返回此堆栈的字符串表示形式。
*@按后进先出顺序返回堆栈中的项目序列,以空格分隔
*/
公共字符串toString(){
StringBuilder s=新的StringBuilder();
用于(项目:本)
s、 追加(项目+“”);
返回s.toString();
}
/**
*返回此堆栈的迭代器,该迭代器按后进先出顺序遍历项。
*@向该堆栈返回一个迭代器,该迭代器按后进先出顺序遍历项目。
*/
公共迭代器迭代器(){返回新的ListIterator();}
//迭代器不实现remove(),因为它是可选的
私有类ListIterator实现了迭代器{
私有节点电流=第一;
公共布尔值hasNext(){返回当前值!=null;}
public void remove(){抛出新的UnsupportedOperationException();}
公共项目下一步(){
如果(!hasNext())抛出新的NoSuchElementException();
项目=当前项目;
当前=当前。下一步;
退货项目;
}
}
//检查内部不变量
私有布尔检查(){
如果(N==0){
if(first!=null)返回false;
}
else如果(N==1){
if(first==null)返回false;
if(first.next!=null)返回false;
}
否则{
if(first.next==null)返回false;
}
//检查实例变量N的内部一致性
int numberOfNodes=0;
for(节点x=first;x!=null;x=x.next){
numberOfNodes++;
}
如果(numberOfNodes!=N)返回false;
返回true;
}
/**
*单元测试LinkedStack数据类型。
*/
公共静态void main(字符串[]args){
LinkedStack s=新LinkedStack();
而(!StdIn.isEmpty()){
String item=StdIn.readString();
如果(!item.equals(“-”)s.push(item);
如果(!s.isEmpty())StdOut.print(s.pop()+);
}
StdOut.println(“(“+s.size()+”堆栈上的左侧)”;
}
}
除了需要使用
check()
方法外,所有内容都很清楚。我不明白的是,为什么在每次操作(即
pop
peek
)之后,我们需要检查堆栈中元素的数量和变量
N
(堆栈的大小)的一致性。我们不是一直保持这两个价值观一致吗?我真的看不出
check()
方法有什么用?

上面的
check()
方法只在中使用

断言可以提供对预期不变量的实时检查。默认情况下,它们被禁用

通常在开发环境中,您可以使用check()方法来检测错误或调试。

check()方法是不需要的。它仅用于断言,在生产环境中是不需要的。