【问题标题】:Collect to list and then pass it in lambda or consumer java 8收集到列表,然后在 lambda 或消费者 java 8 中传递它
【发布时间】:2018-07-13 14:52:08
【问题描述】:

是否可以使用.collect(Collectors.toList()) 收集到列表,然后如果列表不为空,则将整个列表(不像.forEach 的东西)转发给某个消费者或函数?我不想声明一个列表变量来将它传递给我的下一个方法并为此使用 if 大括号。

【问题讨论】:

  • 是的,有可能:.collect(Collectors.toList()).forEach(element -> consumer.action(element))
  • someMethod(stream.collect(toList()))?但这通常会使代码更难阅读、理解和调试。局部变量有什么问题?
  • 我想将整个列表传递给方法,如果它不为空,那就是问题所在。我不想使用空列表触发方法,并且希望在没有任何 ifs 块的情况下执行此操作。
  • if 块有什么问题?使用变量。使用如果。它们很有用。他们没有任何问题。

标签: java java-stream consumer


【解决方案1】:

您似乎正在考虑这样做:

someMethod(...collect(Collectors.toList()));

但只有在传入的列表不为空时才调用someMethod,同时避免if语句和临时变量。

事实上,在传入数据的时候阻止方法调用是不可能的。

您的选择是有限的,它们如下:

  1. 在调用 someMethod 之前将列表存储到一个临时变量中,检查 !tempList.isEmpty() 是否为真,然后使用列表调用方法,否则什么也不做。
  2. 将处理作为someMethod 中的第一件事,如果列表为空,则立即退出该方法,如果它是return;,则使用void 返回方法,否则抛出异常或返回一些值以指示列表不能进行处理。

【讨论】:

  • 如果提问者真的设置为避免if 块,则可能还有另一个复杂的选项:将...collect(toList()) 包裹在Optional.of 中,然后调用filter(list -> !list.isEmpty()).ifPresent(list -> someMethod(list))。 ..虽然我不推荐这个。
  • @Slaw 好声音!这实际上是一个聪明的想法,但可能太聪明了。最终,如果 OP 只是从中获得一些乐趣,那么我想使用这种方法没有害处,但应该避免生成代码,因为它会失去可读性,正如你所暗示的那样。
【解决方案2】:

假设你有以下两种方法:

private boolean canConsumeList(List<?> list) {
    return !list.isEmpty();
}

private <T> void consumeNonEmptyList(List<T> nonEmptyList) {
    // logic here
}

您可以像这样“破解”Collector API:

public final class ExtraCollectors {

    public static <T, R> Collector<T, ?, ?> collectingAndConsuming(Collector<T, ?, R> downstream, Predicate<R> resultFilter, Consumer<R> resultConsumer) {
        return Collectors.collectingAndThen(downstream, result -> {
            if (resultFilter.test(result)) {
                resultConsumer.accept(result);
            }
            return null;
        });
    }
}

然后按如下方式使用:

Stream.of("a", "b").collect(ExtraCollectors.collectingAndConsuming(
        Collectors.toList(), this::canConsumeList, this::consumeNonEmptyList
));

但是请注意,这样的解决方案并不是我认为的“干净代码”(这就是我称之为“黑客”的原因)。对于其他开发人员来说,这可能是不直观的,因为collect 与获得一些结果并置(或者,换句话说,将Stream 的元素“收集”到一个结果中)。在这里,没有结果(甚至我的 IDE 都抱怨“Stream.collect() 的结果被忽略了”)。

【讨论】:

    猜你喜欢
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多