Java:Null Pointer Deque Iterator

时间:2015-04-20 03:20:03

标签: java exception iterator

我已被分配编写一个以中缀表示法取数学表达式的类,并将该表达式转换为后缀表示法中的等效表达式。那部分我已经完成了。

我还被分配编写一个迭代器,让客户端代码迭代后缀表达式的标记。

所以,到目前为止,我对迭代器的代码是:

class PostfixIterator implements Iterator<String> { //this is line 117

private Deque<String> postfix;

public PostfixIterator(Deque<String> postfix) {
    this.postfix = postfix;
}

public boolean hasNext() {
    return postfix.isEmpty();
}

public String next() {
    return postfix.pop(); //this is line 130
}

}

当我尝试创建迭代器的一个实例并调用其中一个方法时,我得到一个空指针异常,我无法弄清楚原因。

这就是我的主要观点:

public static void main(String[] args){
    InfixToPostfix a = new InfixToPostfix("(123)^45+6*7/89");
    Iterator itr = a.iterator();
    System.out.println(itr.next());

}

根据我的编译器,返回postfix.pop()正在评估为null。我不确定为什么。

那么,有人可以帮我解决这个问题并解释为什么我现在所做的不起作用吗?

由于

这是我的整个InfixToPost修复课程:

import java.util.*;

public class InfixToPostfix{

    private Deque<String> postfix;

    public InfixToPostfix(String infix){

        Deque<String> postfix = new LinkedList<String>();
        Deque<String> infixQ = new LinkedList<String>();

        //tokenize the user input
        int i = 0;
        char ch;
        infix = infix.replaceAll("\\s","");//make sure there is no whitespace
         while(i < infix.length()){
             ch = infix.charAt(i);

             if(ch == '(' || ch == ')'|| ch == '+'|| ch == '-' 
                     || ch == '/' || ch == '%'|| ch == '*' 
                     || ch == '^'){
                 String s =ch+"";
                 infixQ.add(s);
                 i++;
             }
             else if (Character.isDigit(ch)){
                 String s ="";
                 int j = i;
                 char c = infix.charAt(j);
                 while(j <= infix.length()-1 && //accumulate the digits in that number
                       Character.isDigit(c = infix.charAt(j))){
                     s = s + c;
                     j++;
                 }
                 infixQ.add(s);
                 i=j;
             }
             else if (Character.isLetter(ch)){
                 String s ="";
                 int j = i;
                 char c = infix.charAt(j);
                 while(j <= infix.length()-1 && //accumulate the lettes in that variable
                       Character.isLetter(c = infix.charAt(j))){
                     s = s + c;
                     j++;
                 }
                 infixQ.add(s);
                 i=j;
             }
        }
        System.out.println(infixQ);

        //start shunting-yard
        Deque<String> stack = new ArrayDeque<String>();
        Iterator<String> itr = infixQ.iterator();
        while(itr.hasNext()){
            String s = itr.next();

            //if token is number or a variable, put it on the output queue
            if(Character.isDigit(s.charAt(0)) 
               || Character.isLetter(s.charAt(0))){
                postfix.add(s);
            }
           if(s.equals("(")){
                stack.push(s);
            }
            if(s.equals(")")){
                while((!stack.isEmpty())&&(!stack.peek().equals("("))){
                    postfix.add(stack.pop());
                }
                stack.pop();
            }
            if(s.equals("+") || s.equals("-")){
                while((!stack.isEmpty()) && (stack.peek().equals("+") 
                     || stack.peek().equals("-")
                     || stack.peek().equals("*") || stack.peek().equals("/")
                     || stack.peek().equals("^"))){
                     postfix.add(stack.pop());

                }
                stack.push(s);
            }
            if(s.equals("*") || s.equals("/") || s.equals("%")){
                if(!stack.isEmpty()){
                    while((!stack.isEmpty())&&(stack.peek().equals("*") 
                          || stack.peek().equals("/") 
                          || stack.peek().equals("%")
                          || stack.peek().equals("^"))){
                        postfix.add(stack.pop());            
                    }
                }
                stack.push(s);
            }
            if(s.equals("^")){
                stack.push(s);
            }       
        }
        while(!stack.isEmpty()){
            postfix.add(stack.pop());
        }
        System.out.println(stack.isEmpty());
        System.out.println(postfix);        
    }

    public Iterator<String> iterator(){
        return new PostfixIterator(postfix);
    }

    public static void main(String[] args){
        InfixToPostfix a = new InfixToPostfix("(123)^45+6*7/89");
        Iterator itr = a.iterator();
        System.out.println(itr.next()); // this is line 112

    }
    }

我的写得不好。我只是需要它才能工作,所以我可以把它打开。

这是我的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
at PostfixIterator.next(InfixToPostfix.java:130)
at PostfixIterator.next(InfixToPostfix.java:117)
at InfixToPostfix.main(InfixToPostfix.java:112)

2 个答案:

答案 0 :(得分:4)

您的问题是关于数据字段范围postfix

这就是你所拥有的:

public class InfixToPostfix{

    private Deque<String> postfix; <-- this is data field 

    public InfixToPostfix(String infix){

        Deque<String> postfix = new LinkedList<String>();
                         ^
                         |   
you declared that reference here again which shadows the data field. 
postfix is just visible in constructor and out of here your data field
is still pointing to null value.

将其更改为

postfix = new LinkedList<String>(); 

因此,您将实例化后缀,当您想要访问它时,它永远不会是null,因为您实例化了数据字段postfix

一些建议:

  1. 您可以使用钻石推理,因为Java 7
  2. 例如:

     List<String> myList = new ArrayList<String>();
    

    可以写

      List<String> myList = new ArrayList< >();
                                          ^
                                          |
    

    如果您可以在下面的代码中为迭代器函数选择不同的名称,那会更好,因为您可能会混淆任何读取代码的人

    public Iterator<String> iterator(){
            return new PostfixIterator(postfix);
        }
    

答案 1 :(得分:1)

似乎你两次声明变量“postfix”,你应该只使用类变量“postfix”。

public class InfixToPostfix{

   private Deque<String> postfix;

   public InfixToPostfix(String infix){

        postfix = new LinkedList<String>();
        // Code here
   }
}