Java: Null Pointer Deque Iterator

Fui designado para escrever uma class que usa uma expressão matemática em notação infixa e transforma essa expressão em uma expressão equivalente na notação pós-fixada. Essa parte eu já completei.

Também fui designado para escrever um iterador que permitisse ao código do cliente iterar sobre os tokens da expressão postfix.

Então, o código que tenho para o meu iterador até agora é:

class PostfixIterator implements Iterator { //this is line 117 private Deque postfix; public PostfixIterator(Deque postfix) { this.postfix = postfix; } public boolean hasNext() { return postfix.isEmpty(); } public String next() { return postfix.pop(); //this is line 130 } } 

Quando tento criar uma instância do meu iterador e chamar um dos methods, obtenho uma exceção de ponteiro nulo e não consigo descobrir o motivo.

Isto é o que meu principal parece:

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

De acordo com o meu compilador, o retorno postfix.pop () está sendo avaliado como null. Eu não tenho certeza porque.

Então, alguém poderia me ajudar a conseguir esse trabalho e possivelmente explicar por que o que eu tenho agora não funciona?

obrigado

Aqui está toda minha class de correção InfixToPost:

 import java.util.*; public class InfixToPostfix{ private Deque postfix; public InfixToPostfix(String infix){ Deque postfix = new LinkedList(); Deque infixQ = new LinkedList(); //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 stack = new ArrayDeque(); Iterator 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 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 } } 

Eu tenho certeza que é mal escrito. Eu só preciso que funcione para que eu possa entregá-lo, no entanto.

E aqui está o meu rastreamento de pilha:

 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) 

Seu problema é sobre o escopo do seu campo de dados postfix

Isto é o que você tem:

 public class InfixToPostfix{ private Deque postfix; <-- this is data field public InfixToPostfix(String infix){ Deque postfix = new LinkedList(); ^ | 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. 

mude para

 postfix = new LinkedList(); 

Como resultado, você irá instanciar o postfix e quando quiser acessá-lo, ele nunca será null porque você instanciou o postfix campo de dados.

Algumas sugestões:

  1. você pode usar inferência de diamante desde o Java 7

Por exemplo:

  List myList = new ArrayList(); 

pode ser escrito

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

e se você pode escolher um nome diferente para sua function de iterador no código abaixo é melhor porque você pode confundir quem lê o seu código

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

Parece que você declara a variável “postfix” duas vezes, você deve usar apenas a variável de class “postfix”.

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