2013-04-30 312 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; 
      } 
     } 
    } 
}