压缩列表列表的3种方法。 有理由更喜欢其中之一吗?

假设我们有一个如下列表。 CoreResult有一个List类型的字段。

 final List list = new LinkedList(SOME_DATA); 

目标是在从每个CoreResult对象中提取特定字段后展平列表。 这里有3种可能的选择。 他们中的任何一个比其他人更好吗?

选项1 :通过map()提取字段并在收集器内展平

 final List A = list.stream().map(CoreResult::getField) .collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll); 

选项2 :通过map()提取字段,通过flatMap() ,简单收集器展平

 final List B = list.stream().map(CoreResult::getField) .flatMap(Collection::stream).collect(Collectors.toList()); 

选项3 :通过flatMap() ,简单的收集器一次性提取一个字段并展平

 final List C = list.stream().flatMap( x -> x.getField().stream()).collect(Collectors.toList()); 

如果不需要从CoreResult中提取任何字段,那么答案是否会有所不同,而是想要简单地展平List<List>

我不确定每个的性能,但java流使用的构建器模式的一个重要方面是它允许可读性 。 我个人认为选项2是最具可读性的。 选项3也很好。 我会避免选择一,因为它有点“欺骗”collections品的扁平化。

将每个方法放在自己的行上,并确定哪个方法最直观。 我更喜欢第二个:

 final List B = list.stream() .map(CoreResult::getField) .flatMap(Collection::stream) .collect(Collectors.toList()); 

我会选择选项2或3.如果你想要压缩List> ,你会这样做:

 List list = doubleList.stream() .flatMap(List::stream) .collect(Collectors.toList()); 

选项3和2是相同的,如果您想首先映射,然后是平面地图或只是平面地图,那么由您决定。

使用选项1,您必须打开另一个流来执行进一步的操作。