2017-03-07 17 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) 
0であるです コンストラクタで警告を抑制するための任意の方法:

ライン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で、意図したとおりではありません。

これに対処する一般的な方法の1つは、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]; 
    } 
} 

注意はまた、あなたはmaxSizeは、新しい値を割り当てることはありませんresizeArray()方法にバグがあります。 array.lengthのように、maxSizeを追跡する必要はありません。

元のコードでスタックが空の場合は、peek()にも問題があると思います。

+0

余計なバグをありがとうございました。元の問題については、私はObjectを使うのは決して快適ではないので、配列をTの配列として保持していましたが、@Lew Blochのように(キャスト後に)コンストラクタ内にObjectの配列を割り当てました。多分それは同じことtho :) – 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); 
}