解决方案:不知道它是否有下一个元素的迭代器
Solution: Iterator which doesn't know if it has a next element
我写了一个迭代器,其中 returns 是另一个给定的无向简单图的固定大小的子图。
它维护一个内部图,该图是当前计算的子图,并具有私有堆栈和列表,从中计算下一个子图。
无法知道迭代器是否可以 return 另一个元素,因为算法可能在尝试找到下一个子图时终止。
在这个设计中,Java 提供的 next()
和 hasNext()
的模式不起作用。我目前使用以下抽象方法编写自己的接口 BlindIterator:
/**
* @return True iff the current element is a valid return.
*/
public boolean hasCurrent();
/**
* @return Returns the current element, but does NOT generate the next element. This method can be called
* as often as wanted, without any side-effects.
*/
public T getCurrent();
/**Generates the next element, which can then be retrieved with getCurrent(). This method thus only provides
* this side-effect. If it is called while the current element is invalid, it may produce and exception,
* depending on the implementation on the iterator.
*/
public void generateNext();
这是一种常见的模式吗?还有比我更好的设计吗?
我相信你创建的相当于Iterator
界面。这是使用 BlindIterator
:
实现 Iterator
class BlindIteratorIterator<T> implements Iterator<T> {
private BlindIterator<T> iterator;
public BlindIteratorIterator(BlindIterator<T> iterator) {
this.iterator = iterator;
iterator.generateNext();
}
@Override
public boolean hasNext() {
return iterator.hasCurrent();
}
@Override
public T next() {
T next = iterator.getCurrent();
iterator.generateNext();
return next;
}
}
您将迭代器实现为 preload/cache 下一个元素(子图)。
例如,如果您的元素来自 Supplier
, where the only method is a get()
method that returns the next element, or null
if no more elements are available, you would implement the Iterator
,如下所示:
public final class SupplierIterator<E> implements Iterator<E> {
private final Supplier<E> supplier;
private E next;
SupplierIterator(Supplier<E> supplier) {
this.supplier = supplier;
this.next = supplier.get(); // cache first (preload)
}
@Override
public boolean hasNext() {
return (this.next != null);
}
@Override
public E next() {
if (this.next == null)
throw new NoSuchElementException();
E elem = this.next;
this.next = supplier.get(); // cache next
return elem;
}
}
有一个很好的 Iterator
实现,可以使用您想要的 BlindIterator
作为元素的来源。
由于您只是发明了 BlindIterator
来解决您认为的 Iterator
的局限性,我建议您不要那样做。使迭代器实现直接调用底层 "generate" 逻辑。
我写了一个迭代器,其中 returns 是另一个给定的无向简单图的固定大小的子图。 它维护一个内部图,该图是当前计算的子图,并具有私有堆栈和列表,从中计算下一个子图。
无法知道迭代器是否可以 return 另一个元素,因为算法可能在尝试找到下一个子图时终止。
在这个设计中,Java 提供的 next()
和 hasNext()
的模式不起作用。我目前使用以下抽象方法编写自己的接口 BlindIterator:
/**
* @return True iff the current element is a valid return.
*/
public boolean hasCurrent();
/**
* @return Returns the current element, but does NOT generate the next element. This method can be called
* as often as wanted, without any side-effects.
*/
public T getCurrent();
/**Generates the next element, which can then be retrieved with getCurrent(). This method thus only provides
* this side-effect. If it is called while the current element is invalid, it may produce and exception,
* depending on the implementation on the iterator.
*/
public void generateNext();
这是一种常见的模式吗?还有比我更好的设计吗?
我相信你创建的相当于Iterator
界面。这是使用 BlindIterator
:
Iterator
class BlindIteratorIterator<T> implements Iterator<T> {
private BlindIterator<T> iterator;
public BlindIteratorIterator(BlindIterator<T> iterator) {
this.iterator = iterator;
iterator.generateNext();
}
@Override
public boolean hasNext() {
return iterator.hasCurrent();
}
@Override
public T next() {
T next = iterator.getCurrent();
iterator.generateNext();
return next;
}
}
您将迭代器实现为 preload/cache 下一个元素(子图)。
例如,如果您的元素来自 Supplier
, where the only method is a get()
method that returns the next element, or null
if no more elements are available, you would implement the Iterator
,如下所示:
public final class SupplierIterator<E> implements Iterator<E> {
private final Supplier<E> supplier;
private E next;
SupplierIterator(Supplier<E> supplier) {
this.supplier = supplier;
this.next = supplier.get(); // cache first (preload)
}
@Override
public boolean hasNext() {
return (this.next != null);
}
@Override
public E next() {
if (this.next == null)
throw new NoSuchElementException();
E elem = this.next;
this.next = supplier.get(); // cache next
return elem;
}
}
Iterator
实现,可以使用您想要的 BlindIterator
作为元素的来源。
由于您只是发明了 BlindIterator
来解决您认为的 Iterator
的局限性,我建议您不要那样做。使迭代器实现直接调用底层 "generate" 逻辑。