由于我具有机械背景,因此我正在学习编程,并且是该领域的新手。 昨天我收到了教授的问题陈述。他为我们提供了一个自定义的迭代器,该迭代器旨在交替遍历给定的元素。
替代迭代器代码如下。
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”方法编写单元测试。
除了队列之外,我们还可以实现其他任何数据结构吗?
我完全不知所措,不明白如何解决这一挑战,但在这里却很困惑。如果你们可以帮助我,那么我可以很快学习重要的概念。
在此先感谢您的帮助。
答案 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之前,我认为将一个/更多迭代器缓冲到一个集合中可能更安全。
编辑:您编写了代码,然后我们可以使用该给定集合的迭代器。是的,我完全忘记了,为简单的队列实现迭代器肯定是毫无意义的:)