2017-03-07 226 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); 
}