试图在Java中实现数组堆栈,但推不工作

问题描述:

我一直在工作了几个小时,现在试图获得基于数组构建和实现的堆栈。我检查了几个来源,看起来像我的ArrayStack类正确构造。但是,当我运行调试时,'head'保持为空,并且大小为& sp回到0:因此,没有任何内容实际上被推入堆栈。有人能帮助我了解我实施的不正确吗?试图在Java中实现数组堆栈,但推不工作

这里是我ArrayStack类:

public class ArrayStack <T>{ 
    protected int sp; //empty stack 
    protected T[] head; //array 
    private int size; 

    @SuppressWarnings("unchecked") 
    public void stack(T t){ 
     sp = -1; 
     size = 24; //sets the default size of the stack 
     head = (T[]) new Object [size]; 
    } 
    public boolean isFull(){ 
     return sp == -1; 
    } 
    public void push (T t){ 
     if (!isFull()) 
      head[++sp] = t; 
    } 
    public T pop(){ 
     if (isFull()){ 
      return null; 
     } 
     else 
      return head[sp--]; //LINE 30 
    } 
} 

这是我的主要方法:

public class StacksAndQsMain { 

    public static void main(String[] args) { 
     //Array Implementation 
     ArrayStack<String> as = new ArrayStack<String>(); 

     String s = "Hello"; 
     String s1 = "World"; 
     String s2 = "Again"; 

     as.push(s); 
     as.push(s1); 
     as.push(s2); 

     System.out.println (as.pop()); //LINE 15 
     System.out.println(); 
     System.out.println (as.pop()); 
     System.out.println(); 
     System.out.println (as.pop()); 
     System.out.println(); 
    } 

} 

最后,这里是我的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException 
at stackAndQs.ArrayStack.pop(ArrayStack.java:30) 
at stackAndQs.StacksAndQsMain.main(StacksAndQsMain.java:15) 

我在公共无效变量推(T t)

this  ArrayStack<T> (id=17) 
head  null 
size  0  
sp  0  
t  "Hello" (id=18) 

我注意到了两件事。

首先像其他人提到的那样,您需要创建一个构造函数并初始化该数组。其次,isFull方法应该检查sp!= this.size -1,基本上确保你不在堆栈实现的24个元素限制处。更改后,isFull您应该否定push方法中的if条件以检查堆栈未满。另外,我会删除pop方法的检查,以检查堆栈isFull是否为了防止某人因为堆栈已满而弹出元素?相反,检查堆栈是否为空。

public class ArrayStack<T> { 
    protected int sp; // empty stack 
    protected T[] head; // array 
    private int size; 

    @SuppressWarnings("unchecked") 
    public ArrayStack() { 
     sp = -1; 
     size = 24; // sets the default size of the stack 
     head = (T[]) new Object[size]; 
    } 

    public boolean isFull() { 
     return sp == this.size -1; 
    } 

    public boolean isEmpty() { 
     return sp == -1; 
    } 

    public void push(T t) { 
     if (!isFull()) 
      head[++sp] = t; 
    } 

    public T pop() { 
     if (isEmpty()) { 
      return null; 
     } else 
      return head[sp--]; // LINE 30 
    } 

    public static void main(String[] args) { 
     // Array Implementation 
     ArrayStack<String> as = new ArrayStack<String>(); 

     String s = "Hello"; 
     String s1 = "World"; 
     String s2 = "Again"; 

     as.push(s); 
     as.push(s1); 
     as.push(s2); 

     System.out.println(as.pop()); // LINE 15 
     System.out.println(); 
     System.out.println(as.pop()); 
     System.out.println(); 
     System.out.println(as.pop()); 
     System.out.println(); 
    } 
} 
+0

谢谢你的时间和解释!我只是盯着Google的isFull()来找出我错过的东西。不胜感激! – Chris 2013-03-14 00:54:47

+0

@ChristopherDay很高兴我能帮到你。 – 2013-03-14 00:57:32

您使用的是默认的构造函数的类,它会将所有的数据成员的初始化为默认值:

public class ArrayStack <T>{ 
protected int sp; //empty stack <-- initialized to 0 
protected T[] head; //array <-- initialized to null 
private int size; // <-- initialized to 0 
// ... snip 
} 

您需要实现默认构造函数这个对象的状态初始化为默认设置你想要(在stack()方法中)。当您调用push时,isFull方法将返回false(作为默认整数值0!= -1)。

而不是实现一个默认的构造函数,你可以在使用它之前调用stack(),但没有理由让你的对象被构​​造成一个陷阱状态!

此外,您isFull方法应该是检查对大小可变的SP,现在它被表现为一个检查的isEmpty :-)

+0

我认为这就是'公共无效堆栈(T t)方法在做什么? – Chris 2013-03-14 00:39:27

+1

@ChristopherDay - 确实如此,但是您并未在上面的主要方法中调用该方法!另外,请参阅我的关于诱惑被困对象的评论!您应该始终确保(如果可能的话)您的物体处于正常状态,并且在施工后可以使用。 – 2013-03-14 00:41:30

+0

请参阅下面的PM 77-1答案,其余的bug与您的isFull在语义上与isEmpty调用相关 – 2013-03-14 00:44:53

您没有使用任何selfdefined构造。您正在使用默认值,这会导致您的sp变量为'0'而不是'-1'。这会导致您推送后的sp值为3,但sp[3]中没有数据,当您尝试弹出数据时会导致NPE。

stack方法更改为

public ArrayStack(T t){ 
     sp = -1; 
     size = 24; //sets the default size of the stack 
     head = (T[]) new Object [size]; 
} 

,使之成为selfdefined构造。

+0

非常感谢你;我不得不作出额外的改变你的建议工作。 – Chris 2013-03-14 00:44:55

按下“Hello”(第1个对象)后sp变为并指定head [0]。从这一刻起,所有进一步的“推送”将不会产生任何结果,因为您的IsFull仍在测试(sp == -1)。