空列表上的 Java 8 流操作

2022-09-01 08:46:17

我只是想知道Java 8在空列表上的行为是什么。

List<?> emptyList = new ArrayList<>();
List<?> processedList = emptyList.stream().collect(Collectors.toList());

这是空列表还是?null

我知道做惰性传播,所以在这种情况下会调用go到方法,或者只是它将在方法结束?collect()stream()


答案 1

collect是终端操作,因此必须对其进行评估。

当终止管道时,你将始终得到一个输出(你永远不会得到)。如果 为空(并且由于流的源为空,或者由于在终端操作之前过滤掉了流的所有元素,因此它是空的并不重要),则输出也将为空。Streamcollect(Collectors.toList())ListnullStreamList


答案 2

您将获得一个空集合。如文档中所述,收集

使用收集器对此流的元素执行可变缩减操作。

可变还原

可变缩减操作在处理流中的元素时,会将输入元素累积到可变结果容器(如集合或 StringBuilder)中。

由于源输入为空或由于筛选器操作,您将获得一个空集合。

感谢您@Andy特纳的提示。

事实上,toList() 累积到一个新列表中,这意味着它不会返回 null。

文档为 Collectors.toList() 提供了以下解释:

返回一个收集器,该收集器将输入元素累积到新 List 中。

我们可以从源代码中获取

    public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

它永远不会产生空输出,但您仍然可以像Andy所示的那样使用自定义收集器获得空值。


推荐