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

2022-09-01 18:50:28

假设我们有一个如下列表。 具有类型 为 的字段。CoreResultList<Double>

final List<CoreResult> list = new LinkedList<>(SOME_DATA);

目标是在从每个对象中提取该特定字段后平展列表。以下是3种可能的选项。他们中的任何一个都比其他的更可取吗?CoreResult

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

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

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

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

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

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

如果不需要从 CoreResult 中提取任何字段,而是想要简单地扁平化一个字段,答案会有所不同吗?List<List<Double>>


答案 1

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

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

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

答案 2

我会选择选项2或3。如果要平展 ,可以执行以下操作:List<List<Double>>

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

推荐