2017-03-07 140 views
1

我想實現一個通用堆棧。通用堆棧實現

這裏的接口

package stack; 

public interface Stack<T>{ 
    void push(T number); 
    T pop(); 
    T peek(); 
    boolean isEmpty(); 
    boolean isFull(); 
} 

這裏的類

package stack; 

import java.lang.reflect.Array; 
import java.util.EmptyStackException; 

public class StackArray <T> implements Stack<T>{ 
    private int maxSize; 
    private T[] array; 
    private int top; 

    public StackArray(int maxSize) { 
     this.maxSize = maxSize; 
//  @SuppressWarnings("unchecked") 
     this.array = (T[]) Array.newInstance(StackArray.class, maxSize); 
     this.top = -1; 
    } 

    private T[] resizeArray() { 
     /** 
     * create a new array double the size of the old, copy the old elements then return the new array */ 
     int newSize = maxSize * 2; 
     T[] newArray = (T[]) Array.newInstance(StackArray.class, newSize); 
     for(int i = 0; i < maxSize; i++) { 
      newArray[i] = this.array[i]; 
     } 
     return newArray; 
    } 

    public boolean isEmpty() { 
     return top == -1; 
    } 

    public boolean isFull() { 
     return top == maxSize-1; 
    } 

    public void push(T element) { 
     if(!this.isFull()) { 
      ++top; 
      array[top] = element; 
     } 
     else { 
      this.array = resizeArray(); 
      array[++top] = element; 
     } 
    } 

    public T pop() { 
     if(!this.isEmpty()) 
      return array[top--]; 
     else { 
      throw new EmptyStackException(); 
     } 
    } 

    public T peek() { 
     return array[top]; 
    } 
} 

這裏的主要類

package stack; 


public class Main { 
    public static void main(String[] args) { 
     String word = "Hello World!"; 
     Stack <Character>stack = new StackArray<>(word.length()); 

//  for(Character ch : word.toCharArray()) { 
//   stack.push(ch); 
//  } 

     for(int i = 0; i < word.length(); i++) { 
      stack.push(word.toCharArray()[i]); 
     } 

     String reversedWord = ""; 
     while(!stack.isEmpty()) { 
      char ch = (char) stack.pop(); 
      reversedWord += ch; 
     } 
     System.out.println(reversedWord); 

    } 
} 

的誤差

Exception in thread "main" java.lang.ArrayStoreException: java.lang.Character 
    at stack.StackArray.push(StackArray.java:40) 
    at stack.Main.main(Main.java:14) 

線40在推法

 array[top] = element; 

邊問: 任何方式抑制在構造函數中警告? :)

+2

難道你不想寫T [] array = new T [maxsize];而不是(T [])Array.newInstance(StackArray.class,maxSize); ? – iMysak

+3

'Array.newInstance(StackArray.class,maxSize);'將爲'StackArray'元素創建一個數組。你正試圖在該數組中放置一個'Character',這是不可能的。 – jlordo

+1

請關注http://stackoverflow.com/q/20557762/814304 – iMysak

回答

2

根本的問題是類型擦除。這意味着一個Stack類的實例在運行時不知道它是類型參數。這就是爲什麼你不能在這裏使用最自然的解決方案,array = new T[maxSize]

你已經嘗試通過使用Array.newInstance(...)創建一個數組來解決這個問題,但不幸的是這個數組並沒有T類型的元素。在顯示的代碼中,元素類型爲StackArray,這可能不是您想要的。處理這個問題

一種常見方法是使用的Object陣列內部到Stack,並澆鑄任何返回值中的存取方法鍵入T。也

class StackArray<T> implements Stack<T> { 
    private int maxSize; 
    private Object[] array; 
    private int top; 

    public StackArray(int maxSize) { 
     this.maxSize = maxSize; 
     this.array = new Object[maxSize]; 
     this.top = -1; 
    } 

    // ... lines removed ... 

    public T pop() { 
     if(this.isEmpty()) 
      throw new EmptyStackException(); 
     return element(top--); 
    } 

    public T peek() { 
     if(this.isEmpty()) 
      throw new EmptyStackException(); 
     return element(top); 
    } 

    // Safe because push(T) is type checked. 
    @SuppressWarnings("unchecked") 
    private T element(int index) { 
     return (T)array[index]; 
    } 
} 

注意你在resizeArray()方法,其中maxSize從未分配一個新值的錯誤。您並不需要跟蹤maxSize,因爲您可以只使用array.length

我認爲當原始代碼中堆棧爲空時,peek()也存在問題。

+0

非常感謝您的額外錯誤。至於最初的問題,我從不習慣使用Object,所以我將數組保存爲T的數組,但在構造函數中(在投射後)爲它指派了一個Object數組,像@Lew Bloch建議的那樣。也許這是一回事:) – MAA

2

你的代碼創建StackArray的陣列,然後嘗試堅持在它的字符對象,就像如果你這樣做:

static void add(Object arr[], Object o) { 
    arr[0] = o; 
} 

public static void main(String[] args) { 
    StackArray stack[] = new StackArray[1]; 
    Character c = 'x'; 
    add(stack, c); 
}