2016-05-21 4 views
3

私は独自のDequeクラスを作成しています。イテレータをオーバーライドする必要があります。円形配列のIteratorをオーバーライドします。

例:配列が[3,4,5、null、null、null、1,2]であるとします。ここで、1は前面、5は終了です。私はイテレータを使用して1から始まり5時に終了する必要があります。

ここで私はDequeクラス全体です。私はhasNextメソッドを除いてイテレータですべてが正しいと信じています。

import java.util.Iterator; 
import java.util.*; 
import javax.swing.border.*; 

public class Deque20<E> implements Iterable<E> { 

    public final int INITIAL_SIZE = 16; 

    private E[] items; 
    private E[] temp; 
    private int size; 
    private int first; 

    @SuppressWarnings("unchecked") // Casting Object[] to E[] 
    public Deque20() { 
     items = (E[]) new Object[INITIAL_SIZE]; 
     size = 0; 
     first = 0; 
    } 

    public void addFirst(E e){ 
     if(size == items.length){ 
      doubleSize(); 
     } 
     first -= 1; 
     if(first == -1){ 
      first = items.length - 1; 
     } 
     items[first] = e; 
     size += 1; 
    } 

    public void addLast(E e){ 
     if(size == items.length){ 
      doubleSize(); 
     } 
     items[(first + size) % items.length] = e; 
     size++; 
    } 

    public void removeFirst(){ 
     items[first] = null; 
     first++; 
     size--; 
    } 

    public void removeLast(){ 
     items[((first + size) % items.length) - 1] = null; 
     size--; 
    } 

    public E peekFirst(){ 
     if(size == 1){ 
      return items[first]; 
     }else{ 
      return items[first]; 
     } 
    } 

    public E peekLast(){ 
     if(size == 1){ 
      return items[first]; 
     }else{ 
      return items[((first + size) % items.length) - 1]; 
     } 
    } 

    @SuppressWarnings("unchecked") 
    private void doubleSize(){ 
     temp = (E[]) new Object[size * 2]; 
     for(int i = 0; i < size; i++){ 
      temp[i] = items[(first + i) % items.length]; 
     } 
     items = temp; 
     first = 0; 
    } 

    @SuppressWarnings("unchecked") 
    private void realign(){ 
     temp = (E[]) new Object[size]; 
     for(int i = 0; i < size; i++){ 
      temp[i] = items[(first + i) % items.length]; 
     } 
     items = temp; 
     first = 0; 
    } 

    public int size(){ 
     return size; 
    } 

    public boolean isEmpty(){ 
     if(size == 0){ 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public Iterator<E> iterator() { 
     Iterator<E> it = new Iterator<E>(){ 
      private int currentIndex = first; 

      @Override 
      public boolean hasNext() { 
       return currentIndex < size && items[currentIndex] != null; 
      } 

      @Override 
      public E next() { 
       return items[currentIndex++]; 
      } 

      @Override 
      public void remove() { 
       throw new UnsupportedOperationException(); 
      } 
     }; 
     return it; 
    } 

    public String toString(){ 
     String str = "["; 
     for(E e : items){ 
      str += e + ","; 
     } 
     str += "]"; 
     return str; 
    } 
} 

EDIT:私の質問は、私はそれだけで前に周りに円をリストの最後に移動しません反復私Iterator.WhenためのhasNextメソッドを修正することができる方法です。

Deque20クラスは、割り当て済みです。ArrayDequeのように動作する独自のクラスを作成する必要があります。

+1

ご質問は何ですか、具体的には? –

+0

円形配列のイテレータをオーバーライドする方法。特にhasNext –

+1

(あなたの質問にそれを編集してください)あなたの現在のソリューションには何が問題なのですか? –

答えて

1

イテレータの内部クラスのコンストラクタでcurrentIndexを初期化し、サイズが超過したときにcurrentIndexを0に設定する必要があります(hasNextは常に次の前に呼び出されると仮定します。 :

 public Iterator() { 
      // init first position - assuming first element is always available somewhere in the array. 
      for (int i = 0;i<items.length;i++) { 
       if (items[i] == first) { 
        currentIndex = i; 
        break; 
       } 
      } 
     } 
    @Override 
    public boolean hasNext() { 
     if (currentIndex >= size()) { 
      currentIndex = 0; 
     } 
     return items[currentIndex] != null; 
    } 

(次がある場合は))(のhasNextなしで呼び出します:

public E next() { 
      if (currentIndex >= size()) { 
       currentIndex = 0; 
      } 
      return items[currentIndex++]; 
     } 
+0

ありがとうございました!私はコンストラクタを必要としませんでした。私はif文を使ってそれがうまくいったかどうかを調べました。 –

0

私はfirstからcurrentOffsetを使用したい:

@Override 
public Iterator<E> iterator() { 
    return new Iterator<E>() { 
     private int currentOffset = 0; 

     @Override 
     public boolean hasNext() { 
      return currentOffset < size; 
     } 

     @Override 
     public E next() { 
      E n = items[(first + currentOffset) % items.length]; 
      currentOffset += 1; 
      return n; 
     } 

     @Override 
     public void remove() { 
      throw new UnsupportedOperationException(); 
     } 
    }; 
} 

また、doubleSize()の名前をdoubleCapacity()と変更することをお勧めします。実際には、両端キューのサイズを変更せずに容量を倍増させるためです。理想的には、イテレート中にデキュスクに対する変更を検出するSimultaneousModificationExceptionの処理を検討するのが理想的です。