使用某种惰性迭代器的最佳方法是什么,只在请求时评估返回值?

时间:2009-10-27 17:28:40

标签: java collections iterator

import java.util.Collection;

import example.Event;

public interface Query
{
    public boolean hasMore ();

    public Collection<Event> getNext ( long count ) throws Exception;
}

这是我想要实现的界面。

实现应该是这样的:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import example.Event;
import example.Query;

public class ListQuery implements Query {

    public ListQuery(List<Event> events, String filter)
            throws FilterParseException {
        // events is the list of given events
        // filter is a string representation of the filter to apply
    }

    public Collection<Event> getNext(long count) throws Exception {
         // returns max. count next entries which match given filter
    }

    public boolean hasMore() {
        // returns if there are more elements matching the given filter
    }
}

我正在考虑的是hasMore()和getNext()之间的关系。在这两种情况下,我都要评估过滤器是否与列表中的元素匹配。可能我不知道给定列表的实现,所以它可能是一个昂贵的操作。显然我不能从迭代器中使用hasNext(),因为我必须检查Event是否符合给定的条件。在我当前的实现中,我有两个不同的迭代器和当前位置,如果getNext()的迭代器的位置大于hasMore()的迭代器的位置,那么hasMore()的位置会向上移动。

我真正想做的是克隆当前的迭代器,而迭代器又用于hasMore(),但这显然是不可能的。

这个问题有更优雅的解决方案吗?

3 个答案:

答案 0 :(得分:5)

不要折磨你自己:-)并且只使用它:

Iterables.filter(Iterable, Predicate)

它为您解决了这些问题。

如果您没有任何Iterable数据,只有Iterator,请参阅相应的类迭代器。如果您需要自己实现Iterator,可能有助于在同一个包中扩展AbstractIterator。

然后,如果您真的想要检索结果块,可以使用Itera *类的partition()方法。

答案 1 :(得分:2)

getNext实现中,在分配返回值之后,可以推进迭代器,直到找到适当的事件。这样,您的hasMore可以安全地测试迭代器上的hasNext,以确定是返回true还是false

答案 2 :(得分:0)

我想你甚至不需要两个迭代器。 hasMore调用可以一直迭代,直到找到匹配并保持不变(如果它已经指向的元素匹配,则不进行迭代)。现在getNext将使用相同的迭代器来迭代和填充返回集合,直到达到计数或找不到更多匹配元素。