Как записать сообщение, если поток в Stream не указан? - PullRequest
4 голосов
/ 10 июля 2019

С учетом следующего потока Java 8:

scheduleService.list().stream()
                      .filter(Schedule::getEnabled)
                      .filter(this::runnable)
                      .flatMap(s -> s.getJobs().stream())
                      // .doSomethingArbitrary(System.out.println("A single message. The total number of 
                      // elements in the stream after filtering is " + this::count))
                      .forEach(this::invoke);

После того, как фильтрация была применена к потоку и после того, как была применена первая операция терминала, я хотел бы либо зарегистрировать сообщение отладки, если поток пустой, либо, если это не так, вызвать метод invoke каждый элемент в потоке. Возможно ли это?

Ответы [ 3 ]

0 голосов
/ 11 июля 2019

Вы можете заключить свой Stream в пользовательский метод, подобный следующему

Stream<???> stream = scheduleService.list().stream()
                                           .filter(Schedule::getEnabled)
                                           .filter(this::runnable)
                                           .flatMap(s -> s.getJobs().stream());

forEachOrElse(stream, this::invoke, () -> System.out.println("The stream was empty"));

С forEachOrElse, являющимся

public <T> void forEachOrElse(Stream<T> inStream, Consumer<T> consumer, Runnable orElse) {
    AtomicBoolean wasEmpty = new AtomicBoolean(true);
    inStream.forEach(e -> {
        wasEmpty.set(false);
        consumer.accept(e);
    });

    if (wasEmpty.get())
        orElse.run();
}

Я не могу проверить это сейчас, но оно должно творить чудеса

0 голосов
/ 12 июля 2019

На самом деле это не совсем "хорошо", но вы можете использовать peek для просмотра вашего потока и установить AtomicBoolean:

AtomicBoolean empty = new AtomicBoolean(true);

scheduleService.list().stream()
                      .filter(Schedule::getEnabled)
                      .filter(this::runnable)
                      .flatMap(s -> s.getJobs().stream())
                      .peek(s -> ab.set(false);)
                      .forEach(this::invoke);

if(empty.get()){
   // is Empty
}
0 голосов
/ 10 июля 2019

Вы всегда можете определить пользовательский преобразователь, который выполняет ведение журнала:

public static Stream<Job> loggingMapper(Service service) {
    if( service.getJobs().isEmpty() ) {
        System.out.println("Empty!"); // Or some other logging code
    }
    return service.getJobs().stream();
}

Тогда

 // same
.flatMap(SomeClass::loggingMapper)

В любом случае ваш преобразователь должен вернуть поток.

...