懒惰地与供应商创建 java 流

Create java stream with supplier lazyly

可以使用 Java 8 个流 API,创建直到需要时才评估的流吗?

我是说。

我有一个处理元素列表的流,在其中一个中间操作(映射)中,我必须读取另一个流,我希望该流位于另一个变量中,以便首先通过所有其他变量使用流对象,但如果没有要处理的对象,我想避免处理第二个流。

我觉得用代码检查更容易:

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);
}

我的疑问是关于第一个流生成,我想 return 基于我处理的列表进行流处理,但我只想在要使用它时这样做(并且对所有消息元素)。

有什么想法吗?

别担心,在您附上 terminal operation 之前,您的 transformationsToApply 不会被评估。

Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.

流不是有状态的,因此没有简单的方法让它只在第一个元素被处理时才做某事。在这种情况下,如果无事可做,您可以尽早检查 messages 参数和 return:

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 流的问题,您需要先将其设为集合,然后才能对其进行多次迭代。