有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java解决方案:迭代器,它不知道是否有下一个元素

我编写了一个迭代器,它返回另一个给定的无向简单图的固定大小的子图。 它维护一个内部图,该图是当前计算的子图,并具有私有堆栈和列表,从中计算下一个子图

不可能知道迭代器是否可以返回另一个元素,因为当试图找到下一个子图时,算法可能会终止

在这个设计中,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();

这是一种常见的图案吗?有比我更好的设计吗


共 (2) 个答案

  1. # 1 楼答案

    实现迭代器来预加载/缓存下一个元素(子图)

    例如,如果您的元素来自^{},其中唯一的方法是返回下一个元素的^{}方法,或者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;
        }
    }
    

    Answer by Joni有一个很好的Iterator实现,可以使用您想要的BlindIterator作为元素的源

    既然你发明BlindIterator只是为了克服你所感知到的Iterator的局限性,我建议你不要这样做。让迭代器实现直接调用底层的“生成”逻辑

  2. # 2 楼答案

    我相信您所创建的相当于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;
            }
        }