Java:Null Pointer Deque Iterator [英] Java: Null Pointer Deque Iterator

查看:128
本文介绍了Java:Null Pointer Deque Iterator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我还被分配了一个迭代器,让客户端代码迭代Postfix表达式的令牌。



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

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

private Deque< String>后缀;

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

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

public String next(){
return postfix.pop(); //这是第130行
}

}

当我尝试创建一个我的迭代器的一个实例,并调用其中一个方法,我得到一个空指针异常,我不知道为什么。



这是我的主要看起来像:

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

}

根据我的编译器,返回postfix.pop()是评估为null。我不知道为什么。



所以,有人可以帮助我得到这个工作,并可能解释为什么我现在不工作?



谢谢



这是我的整个InfixToPost修复类:

  import java.util。*; 

public class InfixToPostfix {

private Deque< String>后缀;

public InfixToPostfix(String infix){

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

//标记用户输入
int i = 0;
char ch
infix = infix.replaceAll(\\s,); //确保没有空格
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&&&& //累加该数字中的数字
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&&& //在该变量中累加lettes
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>();
迭代器< String> itr = infixQ.iterator();
while(itr.hasNext()){
String s = itr.next();

//如果令牌是数字或变量,将其放在输出队列上
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((! .isEmpty())及及(STAC k.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()); //这是第112行

}
}

我他的写作很差。我只需要它的工作,所以我可以把它,但是。



这里是我的堆栈跟踪:

 线程中的异常主要java.lang.NullPointerException 
在PostfixIterator.next(InfixToPostfix.java:130)
在PostfixIterator.next(InfixToPostfix.java:117)
在InfixToPostfix.main(InfixToPostfix.java: 112)


解决方案

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



这是你所拥有的:

  public class InfixToPostfix {

private Deque< String>后缀; < - 这是数据字段

public InfixToPostfix(String infix){

Deque< String> postfix = new LinkedList< String>();
^
|
你再次声明这里引用了这个数据字段的阴影。
postfix只是在构造函数中可见,而在这里你的数据字段
仍然指向空值。

将其更改为

  postfix = new LinkedList< String>(); 

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



一些建议:


  1. 您可以使用因为 Java 7

例如:

 列表< String> myList = new ArrayList< String>(); 

可以写

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

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

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


I've been assigned to write a class that takes a mathematical expression in infix notation and turns that expression into an equivalent one in postfix notation. That part I've already completed.

I was also assigned to write an iterator that would let client code iterate over the tokens of the postfix expression.

So, the code I have for my iterator so far is:

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
}

}

When I try to create an instance of my iterator and call one of the methods, I get a null pointer exception and I can't figure out why.

This is what my main looks like:

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

}

According to my compiler, return postfix.pop() is evaluating to null. I'm not sure why though.

So, could someone help me get this working and possibly explain why what I have now doesn't work?

Thanks

Here is my entire InfixToPost fix class:

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

    }
    }

I'm positive its poorly written. I just need it to work so I can turn it in, though.

And here is my stack trace:

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)

解决方案

You problem is about scoping of your data field postfix

This is what you have :

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.

change it to

postfix = new LinkedList<String>(); 

as a result you will instantiate the postfix and when you want to access it , it will never be null because you instantiated the data field postfix.

Some Suggestions:

  1. you can use diamond inference since Java 7

For example:

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

can be written

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

and if you can choose different name for your iterator function in below code is better because you may confuse whoever reads your code

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

这篇关于Java:Null Pointer Deque Iterator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆