使用单元测试创​​建自定义迭代器

时间:2018-10-13 13:06:45

标签: java junit collections iterator

由于我具有机械背景,因此我正在学习编程,并且是该领域的新手。 昨天我收到了教授的问题陈述。他为我们提供了一个自定义的迭代器,该迭代器旨在交替遍历给定的元素。

替代迭代器代码如下。

import java.util.Iterator;

import java.util.LinkedList;

import java.util.Queue;

public class AlternatingIterator<E> implements Iterator{

private final Queue<E> queue = new LinkedList<>();

public AlternatingIterator(Iterator<E> ... iterators) {
    for(Iterator<E> iterator : iterators) {
        while(iterator.hasNext())
            queue.add(iterator.next());
    }
}

@Override
public boolean hasNext() {
    return queue.isEmpty() ? false : true;
}

@Override
public Object next() {
    return queue.poll();
}

}

现在,AlternatingIterator应该在其构造函数中接收的迭代器之间按顺序交替。例如,如果使用三个迭代器[a,b,c],[1,2]和[x,y,z]构造,则迭代器应按以下顺序生成元素:'a,1,x,b,2,y ,c,z'

我还必须为“ hasNext”和“ next”方法编写单元测试。

除了队列之外,我们还可以实现其他任何数据结构吗?

我完全不知所措,不明白如何解决这一挑战,但在这里却很困惑。如果你们可以帮助我,那么我可以很快学习重要的概念。

在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

队列在这里很有用,但对您的使用方式没有帮助。

将提供给构造函数的迭代器中的所有元素复制到队列中,然后从该队列中实现自定义迭代器是没有意义的:如果要将元素放入已经实现{ 1}},您也可以只使用该Iterable的迭代器。

但这不是练习的重点:您可以在消耗输入迭代器方面懒惰地执行此操作。 (此外,如果其中一个迭代器是无限的...)

我建议的想法是让迭代器(而不是元素)排队。这是您如何做的描述;我不想给您代码来破坏您的学习经验:

  • 在构造函数中,将参数中的迭代器放入队列中。
  • 要实现Iterable,请从hasNext()为假的队列的头部弹出迭代器;否则为false。当队列顶部的迭代器具有下一个元素(在这种情况下返回true),或者队列为空(在这种情况下返回false),则停止。
  • 要实现hasNext(),请从队列中弹出head迭代器,并获取其下一个元素:这就是您将返回的内容。但是,在这样做之前,如果迭代器包含更多元素,请将其推入队列的尾部(这样做意味着您将在下一次迭代中查看下一个迭代器)。

答案 1 :(得分:1)

当然,我们可以使用我们可以想象的任何东西。以下实现是动态交替的。我没有使用队列,而是将所有收到的迭代器存储在一个数组中:

<?xml version="1.0" encoding="utf-8" ?>
<local:MyTabbedPage   

    <TabbedPage.Children>

        <NavigationPage Title="Browse">     
        </NavigationPage>   

    </TabbedPage.Children>
</local:MyTabbedPage>

但是可以使用队列静态地进行同样的操作,将迭代器中的所有元素放入队列,并且只有一个队列(如您的教授代码中一样)。

@Andy Turner:从迭代器收集元素会导致整个过程一直不依赖于源集合,直到没有获得最后一个元素为止。当然,在Java8中,我们使用了import java.util.Iterator; /**Alternates on the given iterators.*/ public class AlternatingIterator<E> implements Iterator { /**Stores the iterators which are to be alternated on.*/ private Iterator<E>[] iterators; /**The index of iterator, which has the next element.*/ private int nextIterator = 0; /**Initializes a new AlternatingIterator object. * Stores the iterators in the iterators field. * Finds the first iterator with an available element.*/ public AlternatingIterator(Iterator<E> ... iterators) { this.iterators = iterators; if (!iterators[0].hasNext()) findNextIterator(); } @Override public boolean hasNext() { return iterators[nextIterator].hasNext(); } @Override public Object next() { E element = iterators[nextIterator].next(); findNextIterator(); return element; } /**Steps on iterators, until one has next element. * It does not step on them infinitely, stops when * the lastly used iterator is reached.*/ private void findNextIterator() { int currentIterator = nextIterator; // Finding iterator with element remaining. do { stepNextIterator(); } while (!iterators[nextIterator].hasNext() && nextIterator != currentIterator); // If it gets around to the same iterator, then there is no iterator with element. } /**Increases the nextIterator value without indexing out of bounds.*/ private void stepNextIterator() { nextIterator = (nextIterator + 1) % iterators.length; } } ,这不会给我们带来并发异常,但是在Java8之前,我认为将一个/更多迭代器缓冲到一个集合中可能更安全。

编辑:您编写了代码,然后我们可以使用该给定集合的迭代器。是的,我完全忘记了,为简单的队列实现迭代器肯定是毫无意义的:)