如果流中的流为空,如何记录消息?

时间:2019-07-10 18:38:35

标签: java java-8 java-stream

给出以下Java 8 Stream:

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流中每个元素上的方法。这可能吗?

4 个答案:

答案 0 :(得分:0)

您总是可以定义一个自定义的映射器来执行日志记录:

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)

无论如何,您的映射器都必须返回流。

答案 1 :(得分:0)

您可以将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();
}

我现在无法对其进行测试,但它应该能够发挥作用

答案 2 :(得分:0)

这根本不是“好”,但是您可以使用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
}

答案 3 :(得分:0)

您可以在将列表转换为peek之前添加stream

public static void main(String[] args) {
    Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5), Collections.emptyList())
            .filter(x -> x.size() % 2 == 0)
            .peek(s -> System.out.println(s.isEmpty()))
            .flatMap(Collection::stream)
            .forEach(System.out::println);
}

输出

false
4
5
true