Java 解决方案:不使用'的迭代器;我不知道它是否有下一个元素
我编写了一个迭代器,它返回另一个给定的无向简单图的固定大小的子图。 它维护一个内部图,该图是当前计算的子图,并具有私有堆栈和列表,从中计算下一个子图 不可能知道迭代器是否可以返回另一个元素,因为可能算法在试图查找下一个子图时终止 在这个设计中,Java提供的Java 解决方案:不使用'的迭代器;我不知道它是否有下一个元素,java,oop,design-patterns,iterator,software-design,Java,Oop,Design Patterns,Iterator,Software Design,我编写了一个迭代器,它返回另一个给定的无向简单图的固定大小的子图。 它维护一个内部图,该图是当前计算的子图,并具有私有堆栈和列表,从中计算下一个子图 不可能知道迭代器是否可以返回另一个元素,因为可能算法在试图查找下一个子图时终止 在这个设计中,Java提供的next()和hasNext()模式不起作用。我目前使用以下抽象方法编写了自己的接口BlindIterator: /** * @return True iff the current element is a valid return.
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();
这是一种常见的模式吗?是否有比我更好的设计?我相信您所创建的与
迭代器
接口相当。下面是使用盲迭代器实现的迭代器
:
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;
}
}
类BlindIterator实现迭代器{
私有盲迭代器;
公共盲迭代器(盲迭代器迭代器){
this.iterator=迭代器;
iterator.generateNext();
}
@凌驾
公共布尔hasNext(){
返回iterator.hasCurrent();
}
@凌驾
公共交通工具{
T next=iterator.getCurrent();
iterator.generateNext();
下一步返回;
}
}
我相信您所创建的相当于迭代器
接口。下面是使用盲迭代器实现的迭代器
:
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;
}
}
类BlindIterator实现迭代器{
私有盲迭代器;
公共盲迭代器(盲迭代器迭代器){
this.iterator=迭代器;
iterator.generateNext();
}
@凌驾
公共布尔hasNext(){
返回iterator.hasCurrent();
}
@凌驾
公共交通工具{
T next=iterator.getCurrent();
iterator.generateNext();
下一步返回;
}
}
实现迭代器以预加载/缓存下一个元素(子图)
例如,如果元素来源于,其中唯一的方法是返回下一个元素的方法,或者null
如果没有更多的元素可用,则实现如下操作:
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;
}
}
公共最终类SupplierIterator实现迭代器{
私人最终供应商;
下一步是私人股本;
供应商迭代器(供应商){
此项。供应商=供应商;
this.next=supplier.get();//先缓存(预加载)
}
@凌驾
公共布尔hasNext(){
返回(this.next!=null);
}
@凌驾
公共教育{
if(this.next==null)
抛出新的NoTouchElementException();
E elem=this.next;
this.next=supplier.get();//缓存下一个
返回元素;
}
}
有一个很好的迭代器
实现,可以使用预期的盲迭代器
作为元素源
由于您发明的盲迭代器
只是为了解决您认为的迭代器
的局限性,因此我建议不要这样做。使迭代器实现直接调用底层的“生成”逻辑。实现迭代器以预加载/缓存下一个元素(子图)
例如,如果元素来源于,其中唯一的方法是返回下一个元素的方法,或者null
如果没有更多的元素可用,则实现如下操作:
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;
}
}
公共最终类SupplierIterator实现迭代器{
私人最终供应商;
下一步是私人股本;
供应商迭代器(供应商){
此项。供应商=供应商;
this.next=supplier.get();//先缓存(预加载)
}
@凌驾
公共布尔hasNext(){
返回(this.next!=null);
}
@凌驾
公共教育{
if(this.next==null)
抛出新的NoTouchElementException();
E elem=this.next;
this.next=supplier.get();//缓存下一个
返回元素;
}
}
有一个很好的迭代器
实现,可以使用预期的盲迭代器
作为元素源
由于您发明的盲迭代器
只是为了解决您认为的迭代器
的局限性,因此我建议不要这样做。让迭代器实现直接调用底层的“generate”逻辑。那么,如果#getCurrent返回当前节点,您将如何进入下一个节点。我认为迭代器在这里可以正常工作,您可以使用#hasNext来确定是否存在下一个有效节点,您当前的节点将始终有效,并且#next将是阻塞/昂贵的调用。然后,您可以围绕#next优化代码,并避免使用#hasnex生成昂贵的代码。如何安全地开始迭代并获取第一个元素?如果在当前元素无效时调用generateNext,它可能会生成和异常,那么如果#getCurrent返回当前节点,您将如何继续下一个节点。我认为迭代器在这里可以正常工作,您可以使用#hasNext来确定是否存在下一个有效节点,您当前的节点将始终有效,并且#next将是阻塞/昂贵的调用。然后,您可以围绕#next优化代码,并避免使用#hasnex生成昂贵的代码。如何安全地开始迭代并获取第一个元素?如果在当前元素无效时调用generateNext,它可能会生成异常“next()
必须抛出NoTouchElementException
,如果hasNext()
将返回false
。问题没有指定当没有当前值时,getCurrent()
做什么,因此迭代器实现