Как лучше всего использовать какой-нибудь ленивый итератор, в котором результат вычисляется только по запросу? - PullRequest
1 голос
/ 27 октября 2009
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 () от итератора, потому что я должен проверить, соответствует ли событие заданным критериям. В моей текущей реализации у меня есть два разных итератора и текущая позиция, где позиция для hasMore () перемещается вверх, если позиция итератора для getNext () больше, чем позиция для hasMore ().

Что я на самом деле хотел бы сделать, так это клонировать текущий итератор, который я, в свою очередь, использовал бы для hasMore (), но это, очевидно, невозможно.

Есть ли более элегантное решение этой проблемы?

Ответы [ 3 ]

5 голосов
/ 04 ноября 2009

Хватит мучить себя :-) и просто используйте это:

Iterables.filter (Итерируемый, Предикат)

Он позаботится об этих проблемах для вас.

Если у вас нет данных ни в чем итерируемом, только в итераторе, посмотрите соответствующий класс итераторов. Если вам нужно реализовать Iterator самостоятельно, это может помочь расширить AbstractIterator в этом же пакете.

Тогда, если вы действительно хотите иметь возможность получать фрагменты результатов, вы можете использовать метод partition () классов Itera * s.

2 голосов
/ 27 октября 2009

В вашей реализации getNext после назначения возвращаемого значения вы можете продвигать свой итератор до тех пор, пока не найдете подходящее событие. Таким образом, ваш hasMore может безопасно протестировать hasNext на вашем итераторе, чтобы определить, возвращать ли true или false.

0 голосов
/ 27 октября 2009

Я думаю, вам даже не нужны два итератора. Вызов hasMore может повторяться до тех пор, пока не найдет совпадение и просто останется там (если элемент, на который он уже указывает, не повторяется). Теперь getNext будет использовать один и тот же итератор для итерации и заполнения возвращаемой коллекции до тех пор, пока не будет достигнуто число или не найдено больше подходящих элементов.

...