Java, как построить поток поверх существующего интерфейса - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть существующий интерфейс, который позволяет мне получить доступ к теоретически бесконечной коллекции следующим образом:

List<Element> retrieve(int start, int end);

//example
retrieve(5, 10); // retrieves the elements 5 through 10.

Теперь я хотел бы построить поток Java поверх этого существующего интерфейса, чтобы я мог передавать какстолько элементов, сколько мне нужно, без запроса большого списка одновременно.

Как бы я поступил так?

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

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018
class Chunk implements Supplier<Element> {
    private final Generator generator;
    private final int chunkSize;
    private List<Element> list = Collections.emptyList();
    private int index = 0;

    public Chunk(Generator generator, int chunkSize) {
        assert chunkSize > 0;
        this.generator = generator;
        this.chunkSize = chunkSize;
    }

    @Override
    public Element get() {
        if (list.isEmpty()) {
            list = generator.retrieve(index, index + chunkSize);
            index += chunkSize;
        }
        return list.remove(0);
    }
}

Здесь я предполагаю, что retrieve возвращает изменяемый список.Если нет, то вам нужно создать новый ArrayList или эквивалент в этой точке.

Это можно использовать как Stream.generate(new Chuck(generator, 30)).Он генерирует бесконечный поток, начинающийся с индекса 0. Вы можете добавить конструктор, который позволяет установить начальный индекс, если это будет полезно.

0 голосов
/ 25 ноября 2018

Я предполагаю, что вы не можете редактировать retrieve метод.

Вы можете сделать это:

IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(x, x).get(0))

Если один член последовательности зависит от предыдущего, это будет означатьпересчитывая каждый термин до n, если вы хотите n th.

Это немного решает проблему, получая его кусками по 100:

IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(1 + (x - 1) * 100, x * 100)).flatMap(List::stream)

Если вы можете редактироватьчто стоит за этим интерфейсом, вы можете просто сделать этот возврат Stream<Element>, используя IntStream.iterate, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...