Java 8 使用流、flatMap 和 lambda

标签 java lambda java-8 java-stream flatmap

我有这段代码,我想返回邮政编码列表:

List<String> postcodes = new ArrayList<>();
List<Entry> entries = x.getEntry(); //getEntry() returns a list of Entry class
for (Entry entry : entries) {
    if (entry != null) {
       Properties properties = entry.getContent().getProperties();
       postcodes.addAll(Arrays.asList(properties.getPostcodes().split(",")));
   }
} 
return postcodes;

这是我尝试使用stream()方法和以下链接方法:

...some other block of code
List<Entry> entries = x.getEntry.stream()
    .filter(entry -> recordEntry != null)
    .flatMap(entry -> {
        Properties properties = recordEntry.getContent().getProperties();
        postCodes.addAll(Arrays.asList(properties.getPostcodes().split(",")));
});

最佳答案

您的代码有几个问题,即:

  1. postCodes.addAll是一个副作用,因此您应该避免这样做,否则当代码并行执行时,您将收到 n非确定性 结果。
  2. flatMap需要一个流,而不是一个 boolean 值;这是您的代码当前尝试传递给 flatMap 的内容.
  3. flatMap在这种情况下,使用一个函数,该函数也使用一个值并返回一个值,并且考虑到您决定使用 lambda 语句 block ,那么您必须在 lambda 语句 block 中包含一个 return 语句,指定要返回的值。您的代码中并非如此。
  4. 流管道由终端操作驱动,这些操作将流转换为非流值,并且您的代码当前根本不会执行 因为您刚刚设置了成分,但实际上并没有从流中请求结果
  5. 您的查询的接收者类型应为 List<String>不是List<Entry>如在当前代码中调用 Arrays.asList(properties.getPostcodes().split(","))返回 List<String>然后通过调用 addAll 将其添加到累加器中.
  6. 感谢 Holger 指出,您经常无法确定变量是否命名为 entryrecordEntry .

这就是我重写代码的方式:

List<String> entries = x.getEntry.stream()
        .filter(Objects::nonNull)
        .map(Entry::getContent)
        .map(Content::getProperties)
        .map(Properties::getPostcodes‌)
        .flatMap(Pattern.co‌mpile(",")::splitAsS‌tream)
        .collect(Collectors.toList());

您可能想使用Collectors.toCollection如果认为合适的话,指定返回列表的具体实现。

编辑:

通过 shmosel 的一些好的建议,我们实际上可以在整个流管道中使用方法引用,从而实现更好的代码意图并且更容易遵循。

或者您可以继续使用该方法:

List<String> entries = x.getEntry.stream()
       .filter(e -> e != null)
       .flatMap(e -> Arrays.asList(
         e.getContent().getProperties().getPostcodes().split(",")).stream()
       )
       .collect(Collectors.toList());

如果你觉得更舒服。

关于Java 8 使用流、flatMap 和 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47895618/

相关文章:

java - android studio java.lang.NoClassDefFoundError Gson

java - Java Concordion 子字符串 ("contains"的解决方法)

java - 如何处理 Sonarlint java :S2259 (Null pointers should not be dereferenced)

c# - 如何通过使用委托(delegate)/lambda 来避免重复代码

c++ - 我应该使用 std::for_each 吗?

lambda - 使用具有自定义条件的 java8 流从另一个对象创建对象列表

java - 使用 scribe oauth facebook 的空指针异常

java - Eclipse 中的 ObservableList<Node> 方法引用错误

用于在多个嵌套循环中验证数据的 Java 8 替代方案

java - 使嵌套的http请求java异步