2017-03-07 3 views
1

제네릭 스택을 구현하려고합니다.일반 스택 구현

여기 여기 클래스 다음

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되는 것입니다 인터페이스

package stack; 

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

입니다 생성자에서 경고를 억제하기 위해 어떤 방법 :

라인 (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]; 
    } 
} 

참고 또한이 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); 
}