Создать Java поток с поставщиком лениво - PullRequest
0 голосов
/ 22 мая 2018

возможно, с помощью API потока Java 8, создать поток, который не оценивается, пока не понадобится?

Я имею в виду.

У меня есть поток, который обрабатывает список элементов,в одной из промежуточных операций (карта) мне нужно прочитать, пройти через другой поток, и я хочу, чтобы этот поток был в другой переменной, которая будет использоваться через все другие объекты первого потока, но если нет объектов для обработки, я бы хотел избежатьобработать второй поток.

Я думаю, что проще проверить с помощью кода:

Message[] process(@Nullable Message[] messages) {
    Stream<Function> transformationsToApply =
            transformations
                    .stream()
                    .filter(transformation -> transformationIsEnabled(transformation.getLeft()))
                    .map(Pair::getRight);

    return Arrays.stream(messages != null ? messages : new Message[0])
            .filter(Objects::nonNull)
            .map(agentMessage -> {
                transformationsToApply.forEach(transformation -> processMessage(transformation, agentMessage));
                return agentMessage;
            })
            .toArray(Message[]::new);
}

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

Любая идея ..?

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Потоки не сохраняют состояние, поэтому нет простого способа заставить его что-либо делать только при обработке первого элемента.В этом случае вы могли бы просто проверить параметр messages и вернуться пораньше, если нечего делать:

Message[] process(@Nullable Message[] messages) {
    if (messages == null || messages.length == 0) return new Message[0];

    List<Function> transformationsToApply = transformations.stream()
            .filter(transformation -> transformationIsEnabled(transformation.getLeft()))
            .map(Pair::getRight)
            .collect(Collectors.toList());

    return Arrays.stream(messages)
            .filter(Objects::nonNull)
            .map(agentMessage -> {
                transformationsToApply.forEach(transformation -> processMessage(transformation, agentMessage));
                return agentMessage;
            })
            .toArray(Message[]::new);
}

Я также исправил проблему с повторным использованием потока transformationsToApply, вам нужно сделать егоколлекции, прежде чем вы сможете повторить ее несколько раз.

0 голосов
/ 22 мая 2018

Не беспокойтесь, ваш transformationsToApply не будет оценен, пока вы не присоедините операцию терминала .

Промежуточные операции возвращают новый поток.Они всегда ленивы;выполнение промежуточной операции, такой как filter (), фактически не выполняет никакой фильтрации, но вместо этого создает новый поток, который при прохождении содержит элементы исходного потока, которые соответствуют данному предикату.Обход источника конвейера не начинается, пока не будет выполнена терминальная операция конвейера.

...