2

我正在尝试创建一个迭代器的迭代器,支持 Java 中的任何类型。目的是迭代迭代器的对象。

但我有一个类型不匹配,我看不到如何初始化我的实现。

我想到的第一个想法是让我的类实现Iterator<Iterator<T>>,但这不起作用,因为下一个方法将具有与public Iterator<T> next()我想要做的不对应的签名。Iterator<T>我不想返回 of ,而是返回 type T

所以我创建了另一个与迭代器接口非常相似的接口:

  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 接口,所以这就是为什么它不是一个好的替代品。我的问题是我不怎么能

4

4 回答 4

3

这行不通,

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再次使用。

于 2013-04-30T10:24:17.643 回答
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);
于 2013-04-30T10:38:50.410 回答
0

您可以使用

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

没有直接从 Java 数组获取迭代器的标准方法,因此您可以先将其转换为 a List,或者为数组构建自己的迭代器。

于 2013-04-30T10:23:06.833 回答
0

IteratorOfIterator 的目的是隐藏处理多个迭代器的实现细节,以便客户端将元素作为单个迭代器进行迭代。从某种意义上说,IterorOfIterator 充当了其他迭代器的适配器。 有关概念,请参阅此页面 - 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;
            }
        }
    }
}
于 2016-11-01T00:44:59.987 回答