Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的代码中会出现“EmptyStackException”?_Java_Exception_Stack_Postfix Notation_Infix Notation - Fatal编程技术网

Java 为什么我的代码中会出现“EmptyStackException”?

Java 为什么我的代码中会出现“EmptyStackException”?,java,exception,stack,postfix-notation,infix-notation,Java,Exception,Stack,Postfix Notation,Infix Notation,当我运行调车场测试(发布的第二个代码)时,我得到一个指向此行的EmptyStackException: @Test public void infix2postfixTest() { assertEquals("3 4 5 6 - 7 * 8 / + - 9 *", s.infix2postfix("3 * ( 4 + ( 5 - 6 ) * 7 / 8 ) - 9")); } 但是逻辑对我来说是有意义的,我是说如果令牌是,那么当堆栈顶部不是时,将堆栈顶部附加到输出并将其从堆栈中移除。我是

当我运行调车场测试(发布的第二个代码)时,我得到一个指向此行的EmptyStackException:

@Test
public void infix2postfixTest()
{

 assertEquals("3 4 5 6 - 7 * 8 / + - 9 *", s.infix2postfix("3 * ( 4 + ( 5 - 6 ) * 7 / 8 ) - 9"));
}
但是逻辑对我来说是有意义的,我是说如果令牌是,那么当堆栈顶部不是时,将堆栈顶部附加到输出并将其从堆栈中移除。我是不是遗漏了什么

以下是我的堆栈窥视方法:

while (!(s.peek().equals("(")))

你一直在不检查它是否为空的情况下弹出和偷看。偷看或弹出一个空堆栈会生成您一直得到的结果。正如您所指出的,Stack类在内部进行检查,但它这样做只是为了生成EmptyStackException。作为peek的来电者,您有责任首先检查您自己!如果您不这样做,那么您已经为堆栈创建了一个不可能的情况-如果空堆栈中没有任何东西可以查看,那么它就无法向您显示查看的结果

您应该替换:

public T peek()
{
    if (isEmpty() == true)
    {
        throw new java.util.EmptyStackException();
    }

    return stack.get(stack.size()-1);
}
类似于:

else if(tokens[i].equals(")"))
{
    while (!(s.peek().equals("(")))
    {
        output.append(s.pop());
    }
    if (s.isEmpty() == true)
    {
        System.out.println("Error: mismatching parentheses");
    }
    s.pop();
}
当然,修复可以以不同于我的示例的方式实现。但问题是,在调用peek或pop之前,必须先检查isEmpty


作为补充说明,我想指出,打印不匹配括号错误的原始代码是不可访问的。if语句在while语句结束后执行,当while语句结束时,保证s堆栈非空!这种保证使后续的pop调用安全,但也意味着错误消息永远不会执行。我在我的示例中修复了这个额外的错误,但我想更详细地解释它,因为否则您可能不会注意到。

永远不要将字符串值与!=,使用s.peek.equals代替。此外,没有异常错误,您应该在问题中添加完整的异常堆栈跟踪。如果尝试在空堆栈中窥视,Stack.peek会引发EmptyStackException。是的,我确实在我的peek中实现了空堆栈异常,错误确实提到了它。您不需要实现它,它已经实现了。或者你的意思是你已经实现了自己的堆栈类?是的,我自己的堆栈类
else if(tokens[i].equals(")"))
{
    while (!(s.peek().equals("(")))
    {
        output.append(s.pop());
    }
    if (s.isEmpty() == true)
    {
        System.out.println("Error: mismatching parentheses");
    }
    s.pop();
}
else if(tokens[i].equals(")"))
{
    while(!s.isEmpty())
    {
        if(s.peek().equals("("))
        {
            s.pop();
            if(s.isEmpty())//we just popped so the while check no longer applies
            {
                System.out.println("Error: mismatching parentheses");
            }
        }
        else
        {
            output.append(s.pop());
        }
    }
}