2017-05-11 60 views
1

我有如下定義一個節點類 -普通推到堆棧提供了編譯錯誤

public static class Node<T> { 
    public T value; 
    public Node<T> left; 
    public Node<T> right; 

    public Node(T value) { 
     this.value = value; 
     left = null; 
     right = null; 
    } 

} 

現在我想添加/推Node<Integer>Stack<Node<T>>,它給了我一個編譯錯誤。

private static <T> Node<T> createTree(Expression expression) { 
    Stack<Node<T>> nodeStack = new Stack<>(); 
    Stack<Token> tokenStack = new Stack<>(); 

    Token token = getNextToken(expression); 

    while (token != null) { 
     if (token instanceof OpenParenthesis) { 
      tokenStack.push(token); 
     } else if (token instanceof Element) { 
      nodeStack.push(new Node<Integer>(((Element) token).value)); // Here 
     } else if (token instanceof EmptyElement) { 
      nodeStack.push(null); 
     } else if (token instanceof CloseParenthesis) { 
      if (nodeStack.size() == 1) { 
       tokenStack.pop(); 
       return nodeStack.pop(); 
      } 

      tokenStack.pop(); 
      Node<T> right = nodeStack.pop(); 
      Node<T> left = nodeStack.pop(); 
      Node<T> node = nodeStack.pop(); 
      node.left = left; 
      node.right = right; 
      nodeStack.push(node); 
     } 

     token = getNextToken(expression); 
    } 

    return null; 
} 

這行不編譯 -

nodeStack.push(new Node<Integer>(((Element) token).value)); 

與消息 -

Stackpush(Node<T>)不能應用於(Node<java.lang.Integer>)

+0

嗯,是的。 'T'可以是任何類型,比如'String'。如果它是一個'String',你怎麼期望在棧上推一個整數?我懷疑你可能不希望'createTree'是通用的;也許它應該返回一個'Node ',這樣你就可以創建一個具有不同類節點的樹。 – ajb

+0

另外,你爲什麼要將'Token'投入到'Number'中?這不會編譯。 – ajb

+0

我的不好,我有一個本地班'Number',這裏我沒有提到。我會重命名它以消除混淆。 –

回答

1

<T>型帕ameter是一個方法級別參數。即你的方法簽名定義它:

private static <T> Node<T> createTree(Expression expression 

你的節點堆棧具有非常相同的類型:

Stack<Node<T>> nodeStack = new Stack<>(); 

所以,當你推入該棧,你需要非常相同類型的令牌:

nodeStack.push(new Node<T>(((Element) token).value)); 
//     ^^^^^^ - using <T> 

那麼,你如何讓它爲你工作?如果您是確保所有推nodeStacknullNode<Integer> - 這是怎麼好像 - 那麼你可以擺脫方法級令牌類型:

private static Node<Integer> createTree(Expression expression) { 
    Stack<Node<Integer>> nodeStack = new Stack<>(); 
    // ... 
    } else if (token instanceof Element) { 
     nodeStack.push(new Node<Integer>(((Element) token).value)); // Here 
    } 
    // ... 
      Node<Integer> right = nodeStack.pop(); 
      Node<Integer> left = nodeStack.pop(); 
      Node<Integer> node = nodeStack.pop(); 
    // ... 
    } 
} 
+0

我知道我可以讓'createTree()'返回一個'Node ',但是,有時候我可以使用'String'而不是'Integer'。我將不得不創建一個單獨的'createTree()'來代替返回'Node '。 –

+0

如果你知道它在編譯時是否是String或Integer,那麼你可以使用類型化方法,即使用'nodeStack.push(新節點(((Element)token).value)); '。在這種情況下,你可以指定''這樣的類型:'OuterClass。 createTree(...)'或'OuterClass。 createTree(...)'。 –

+0

你可以看看[這裏]的問題(https://codereview.stackexchange.com/questions/163061/creating-a-tree-from-an-input-string-1-2-3-10-11- 15-4-5-13-6) - 我增加了更多細節。這可能會澄清我想說的話。我不想在這裏編輯這個問題(它可能會改變我之前提出的問題)。 –