2013-04-30 174 views
1

我想創建一個迭代器的迭代器,支持Java中的任何類型。目的是遍歷迭代器的對象。迭代器的迭代器

但我有一個類型不匹配,我看不到如何初始化我的實現。

我想到的第一個想法是讓我的課程實現Iterator<Iterator<T>>,但這不起作用,因爲下一個方法的簽名public Iterator<T> next()不符合我想要做的事。我不想返回Iterator<T>,我想返回類型T

所以我創建另一個界面非常相似的Iterator接口:

public interface MyIterator<T extends Iterator<T>> { 

    public boolean hasNext(); 

    public T next(); 
} 

我的迭代器需要一個類型T是一個迭代器。下面是我的實現(不刪除):

public class IteratorOfIterator<T extends Iterator<T>> implements MyIterator<T> { 

private T[] iterators; 

private T currentIterator; 

private int currentIndex; 

public IteratorOfIterator(T[] iterators){ 
    this.iterators = iterators; 
    this.currentIndex = 0; 
    this.currentIterator = iterators[currentIndex]; 
} 

public boolean hasNext() { 
    return currentIndex < iterators.length - 1 || currentIterator.hasNext(); 
} 

public T next() { 
    if(!this.currentIterator.hasNext()){ 
     currentIndex++; 
     this.currentIterator = iterators[currentIndex]; 
    } 
    return currentIterator.next(); 
} 

如果我想測試我的迭代器,但我有一個類型不匹配,我怎麼能初始化呢?這裏有一個例子我想做的事:

String[] strings = {"peanut","butter","coco","foo","bar"}; 

Object[] iterators = {strings}; 

MyIterator<String> myIterator = new IteratorOfIterator<String>(iterators); // <-- in this line 

錯誤說:Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends Iterator<T>> of the type IteratorOfIterator<T> IteratorOfIterator.java

我怎樣才能解決這個問題?非常感謝您的建議。 PS:我完全理解這個問題。我明白,例如,String類型沒有實現MyIterator接口,所以這就是爲什麼它不是一個好的替代品。我的問題是我不知道怎樣才能

回答

2

這是行不通的,

public interface MyIterator<T extends Iterator<T>> 

這意味着T必須是Iterator本身。

你不想做T被限制在一個特定的類型,

public interface MyIterator<T> 

,但你希望你的迭代器爲類型Iterator<T>

public class IteratorOfIterator<T> implements Iterator<T> { 

private Iterator<T>[] iterators; 

private Iterator<T> currentIterator; 

private int currentIndex; 

public IteratorOfIterator(Iterator<T>[] iterators){ 
    this.iterators = iterators; 
    this.currentIndex = 0; 
    this.currentIterator = iterators[currentIndex]; 
} 

所以你可以使用Iterator代替MyIterator再次。

+0

好吧,我要檢查一下 – Dimitri 2013-04-30 10:33:12

0

您可以使用

Iterator<String> myIterator = Arrays.asList(strings).iterator(); 

沒有標準的方式來直接獲取Java數組迭代器,所以您可以先將其轉換爲一個List,或爲數組構建自己的迭代器。

0

要創建迭代的迭代器和構造函數定義迭代器的陣列,所以調用代碼應該是這樣的:

List list1 = new ArrayList(); 
    List list2 = new ArrayList(); 
    Iterator<String> iterator1 = list1.iterator(); 
    Iterator<String> iterator2 = list2.iterator();  
    Iterator[] iteratorList = {iterator1, iterator2};  
    MyIterator<String> myIterator = new IteratorOfIterator(iteratorList); 
0

IteratorOfIterator的目的是隱藏處理多個迭代器的實現細節,所以客戶端遍歷元素作爲單個迭代器。從某種意義上講,IterorOfIterator充當其他迭代器的適配器。See this page for the concept - RoundRobinIterator

此處的代碼利用隊列來維護迭代器序列。 'currentIter'變量由隊列中的輪詢設置。 setNext是一個狀態機,它在迭代器之間轉換並設置下一個值以迭代。

public class IteratorOfIterator<T> implements Iterator<T> { 
private final Queue<Iterator<T>> iterQueue; 
private Iterator<T> currentIter; 
private T nextValue; 

public IteratorOfIterator(List<Iterator<T>> iters) { 
    this.iterQueue = new LinkedList<Iterator<T>>(iters); 
    this.currentIter = null; 
    this.nextValue = null; 
} 

@Override 
public boolean hasNext() { 
    return this.nextValue != null || setNext(); 
} 

@Override 
public T next() { 
    if (this.nextValue != null) { 
     T next = this.nextValue; 
     this.nextValue = null; 
     setNext(); 
     return next; 
    } 
    return null; 
} 

private boolean setNext() { 
    while (true) { 
     if (currentIter == null && iterQueue.isEmpty()) { 
      return false; 
     } 
     if (currentIter == null && !iterQueue.isEmpty()) { 
      currentIter = iterQueue.poll(); 
     } 
     if (currentIter != null && currentIter.hasNext()) { 
      this.nextValue = currentIter.next(); 
      return true; 
     } 
     if (currentIter != null && !currentIter.hasNext()) { 
      if (!iterQueue.isEmpty()) { 
       currentIter = iterQueue.poll(); 
      } else { 
       currentIter = null; 
      } 
     } 
    } 
}