JavaDoc for Stream.collect()表示返回the result of the reduction
。这并没有告诉我这样的代码是否可以为filteredList返回null:
List<String> filteredList = inputList.stream().
filter(c -> c.getSomeBoolean()).
flatMap(c -> {
List<String> l = new ArrayList<String>();
l.add(c.getSomething());
l.add(c.getSomethingElse());
return l.stream();
}).
filter(s -> StringUtils.isNotBlank(s)).
collect(Collectors.toList());
我希望如果它可以返回null,那么它将返回Optional,但它也没有说明。
是否记录Stream.collect()是否可以返回null?
答案 0 :(得分:14)
Collector.toList()
将为您返回空列表。
以下是实施:
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);
}
正如您所看到的,ArrayList::new
被用作您商品的容器。
我在这里看到了很多疑问,所以我阅读了JavaDoc并与您分享:
来自Collector的JavaDoc:
公共接口收集器
可变减少操作 可选地将输入元素累积到可变结果容器中 将累积结果转换为最终表示 所有输入元素都已处理完毕。减少操作可以 顺序或并行执行。
收集器由四个一起工作的函数指定 将条目累积到可变结果容器中,并且可选地 对结果执行最终转换。他们是:
创建新的结果容器(供应商())
将新数据元素合并到结果容器(accumulator())
- 将两个结果容器合并为一个(合并器())
- 对容器执行可选的最终转换(finisher())
和
使用收集器顺序实现减少 使用供应商功能创建单个结果容器,并且 为每个输入元素调用一次累加器函数。一个 并行实现会对输入进行分区,创建结果 每个分区的容器,累积每个分区的内容 分区为该分区的子结果,然后使用 合并器函数将子结果合并为一个组合结果。
因此,只要您不执行组合函数返回null
等奇怪的操作,Collector
始终使用您提供的mutable container
函数返回至少supplier
。
如果一个实现能够返回null
容器,我认为这是违反直觉的。
答案 1 :(得分:5)
这不取决于Stream.collect
,而取决于个人Collector
。 Collectors.toList()
将返回空的ArrayList
。
也就是说,在某些情况下,没有人不能使用奇怪的Collector
来返回null:
.collect(
Collector.of(
ArrayList::new,
ArrayList::add,
(a, b) -> {
a.addAll(b);
return a;
},
a -> a.isEmpty() ? null : a // finisher replaces empty list with null
)
);
所以Collector
是您需要记住检查的事情。我相信所有Collectors
available out-of-the-box都会返回空集合,正如您所期望的那样。
答案 2 :(得分:2)
我认为文档的这一部分说它不能为空:
返回一个收集器,用于将输入元素累积到 ne w中 的列表强>
精彩集锦由我添加。我认为这个新列表意味着什么不是空的。
我开始检查ReferencePipeline.collect()
以检查实际实施是否属实。不幸的是,这是徒劳的尝试。这里有很多案例,就像它是平行的吗?它是在forEach
之后吗?等
答案 3 :(得分:1)
这是收集器依赖的。你正在使用的那个(Collectors.toList())返回一个空列表。
答案 4 :(得分:0)
没有collect绝不会返回null,为了检查使用isEmpty()
而不是null
答案 5 :(得分:0)
您可以使用Collectors::collectingAndThen
将collect()结果传递给Function<T,R>
。 Function<T,R>
的返回值将是collect()的返回值。
List<String> filteredList = inputList.stream()
.filter(c -> c.isActive())
.collect(Collectors.collectingAndThen(Collectors.toList(), c -> !c.isEmpty()?c:null));