我正在学习编程,并且是这个领域的新手,因为我有机械背景。 昨天我收到了教授的问题陈述,他为我们提供了一个自定义迭代器,旨在替代迭代给定的元素。
备用迭代器代码如下所示。
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();
}
}
现在,交替迭代器应该按顺序在其构造函数中接收的迭代器之间交替。 例如,如果用三个迭代
器 [a,b,c]、[1,2] 和 [x,y,z] 构造,迭代器应按此顺序生成元素 'a, 1, x, b, 2, y, c, z'我还必须为"hasNext"和"next"方法编写单元测试。
我们可以实现队列以外的任何其他数据结构吗?
我完全被吹走了,厌倦了如何解决这个挑战,但在这里非常困惑。如果你们能帮助我,那么我可以很快学会重要的概念。
提前感谢您,任何帮助将不胜感激。
当然,我们可以使用任何我们能想象到的东西。以下实现动态交替。我没有使用队列,而是将所有收到的迭代器存储在一个数组中:
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;
}
}
但是也可以使用队列静态地进行相同的操作,对迭代器中的所有元素进行排队,就像您(您的教授(代码中一样,只有一个队列。
@Andy Turner:从迭代器收集元素会导致在未获得最后一个元素之前一直不依赖源集合。当然,从 Java8 开始,我们使用Stream
s,这不会给我们带来并发异常,但在 Java8 之前,在我看来,将一个或多个迭代器缓冲到集合中可能更安全。
编辑:你写了,然后我们可以使用给定集合的迭代器。是的,我完全忘记了,为简单队列实现迭代器肯定是毫无意义的:)
队列在这里很有用,但对你使用它的方式没有帮助。
将所有元素从提供给构造函数的迭代器复制到队列中,然后从该队列实现自定义迭代器是没有意义的:如果要将元素放入已经实现Iterable
的集合中,则不妨使用该Iterable
的迭代器。
但这也可能不是练习的重点:对于使用输入迭代器,您可以懒惰地执行此操作。(此外,如果其中一个迭代器是无限的怎么办...
我建议的想法是制作一个迭代器队列,而不是元素。这是如何做到这一点的描述;我不想给你代码来破坏你的学习体验:
- 在构造函数中,将参数中的迭代器放入队列中。
- 要实现
hasNext()
,从hasNext()
为 false 的队列头部弹出迭代器;当队列头部的迭代器具有下一个元素(在这种情况下返回 true(或队列为空(在这种情况下返回 false(时停止。 - 要实现
next()
,将头迭代器从队列中弹出,并获取其下一个元素:这就是您将返回的内容。但是,在你这样做之前,如果迭代器有更多的元素,把它推到队列的尾部(这样做意味着你将在下一次迭代中查看下一个迭代器(。