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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39019857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:49:01  来源:igfitidea点击:

3 ways to flatten a list of lists. Is there a reason to prefer one of them?

javajava-8java-stream

提问by 3VYZkz7t

Assume we have a list as follows. CoreResulthas a field of type List<Double>.

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

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

The objective is to flatten the list after extracting that specific field from each CoreResultobject. Here are 3 possible options. Is any one of them preferable to the others?

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

Option 1: extract a field via map()and flatten inside collector

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

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

Option 2: extract a field via map(), flatten via flatMap(), simple collector

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

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

Option 3: extract a field and flatten in one go via flatMap(), simple collector

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

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

Would the answer be different if there was no need to extract any field from CoreResult, and instead one wanted to simply flatten a List<List<Double>>?

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

采纳答案by Zircon

I'm not sure about the performance of each one, but an important aspect of the builder pattern utilized by java streams is that it allows for readability. I personally find the option 2 to be the most readable. Option 3 is good, too. I would avoid option one because it kind of "cheats" the flattening of the collection.

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

Put each method on its own line and determine which is the most intuitive to read. I rather like the second one:

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

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

回答by ByeBye

Option 3 and 2 is same, so up to you if you want to map first and then flat map or just flatmap.

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

With option 1 you have to open another stream to perform further operations.

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

回答by marstran

I would go for option 2 or 3. If you want to flatten a List<List<Double>>, you would do this:

我会选择选项 2 或 3。如果你想展平 a List<List<Double>>,你可以这样做:

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