简体   繁体   English

收集列表,然后将其传递给lambda或Consumer Java 8

[英]Collect to list and then pass it in lambda or consumer java 8

Is it possible to collect to list using .collect(Collectors.toList()) and then pass this whole list (not like .forEach stuff) forward to some consumer or function if the list is not empty? 是否可以使用.collect(Collectors.toList())收集列表,然后将整个列表(与.forEach东西不同)传递给某些使用者或函数(如果列表不为空)? I don't want to declare a list variable to pass it to my next method and use if braces for this. 我不想声明一个列表变量将其传递给我的下一个方法,并为此使用大括号。

It seems that you're thinking of doing something along the lines of this: 似乎您正在考虑按照以下方式进行操作:

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

But only invoke the someMethod if the passed in list is not empty while avoiding if statements and temporary variables. 但是,仅当传递的列表不为空时才调用someMethod ,同时避免使用if语句和临时变量。

Matter of fact is It's not possible to prevent the method invocation at the point of passing data in. 实际上很重要的一点是,无法在传入数据时阻止方法调用。

Your options are limited and they're as follows: 您的选择是有限的,它们如下:

  1. Store the list into a temporary variable before the call to someMethod , check if !tempList.isEmpty() and if that's true then invoke the method with the list else do nothing. 将列表存储在调用someMethod之前的临时变量中,检查!tempList.isEmpty()是否正确,然后使用列表调用该方法,否则不执行任何操作。
  2. Do the handling as the first thing in the someMethod and exit the method immediately if the list is empty using return; 作为someMethod的第一件事进行处理,如果列表为空,则使用return;立即退出该方法return; if it's a void returning method else throw an exception or return some value to indicate the list cannot be processed. 如果它是一个void返回方法,则抛出异常或返回一些值以指示列表无法处理。

Assuming you've got the following two methods: 假设您有以下两种方法:

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

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

you could "hack" the Collector API like this: 您可以像这样“入侵” 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;
        });
    }
}

and then use it as follows: 然后按如下方式使用它:

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

Note, however, that such a solution isn't something I'd consider "clean code" (that's why I called it a "hack"). 但是请注意,这种解决方案不是我认为的“干净代码”(这就是为什么我称其为“ hack”)的原因。 It may be unintuitive for other developers because collect collocates with obtaining some result (or, in other words, "collecting" the elements of the Stream into a single result). 对于其他开发人员而言,这可能并不直观,因为collect与获得某些结果(或换句话说,将“ Stream ”的元素“收集”到单个结果中) Stream And here, there's no result (even my IDE complains that the "result of Stream.collect() is ignored"). 在这里,没有任何结果(甚至我的IDE都抱怨“ Stream.collect()结果被忽略”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM