【问题标题】:Java: Null Pointer Deque IteratorJava:空指针双端队列迭代器
【发布时间】:2015-06-26 15:25:29
【问题描述】:

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

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

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

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());

}

根据我的编译器,return 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)

【问题讨论】:

  • 你的 InfixToPostfix 类在哪里?我不明白 PostfixIterator 将如何迭代 InfixToPostfix?!!!您需要发布更多信息
  • 如果 postfix.pop() 返回 null 那么它将被打印为 null,只是因为 "itr" 本身为 null 就会发生异常。请验证这一点。
  • 你能发布你的 InfixToPostfix 课程吗?做 a.iterator();正确返回您的 PostfixIterator 类?
  • 现在你需要发布你的堆栈跟踪 plz
  • 发布了我的堆栈跟踪。

标签: java exception iterator


【解决方案1】:

您的问题是关于数据字段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

例如:

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

可以写

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

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

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

【讨论】:

    【解决方案2】:

    好像你声明了两次变量“postfix”,你应该只使用类变量“postfix”。

    public class InfixToPostfix{
    
       private Deque<String> postfix;
    
       public InfixToPostfix(String infix){
    
            postfix = new LinkedList<String>();
            // Code here
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 2014-03-14
      • 2017-05-20
      • 1970-01-01
      相关资源
      最近更新 更多