Java 8 Stream从返回值添加新对象到列表

Ric*_*ard 3 java java-8 java-stream

我想保存方法的返回值,并使用它来创建一个新的对象,添加到列表中.以下是更清晰的代码块:

final List<FooBoo> fooboos = new ArrayList<>();
for (Foo foo : foos) {
    Optional<Boo> boo = generateBoo(foo);
    if (boo.isPresent()) {
        fooboos.add(new FooBoo(foo, boo.get()));
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过这样的事情:

fooboos = foos
            .stream()
            .map(f -> generateBoo(f))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但显然我在这里错过了一些实际创建FooBoo对象的东西.我如何使用java流方法完成这项工作?

JB *_*zet 6

fooboos = foos
        .stream()
        .map(foo -> generateBoo(foo).map(boo -> new FooBoo(foo, boo))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 因为你需要`foo`. (2认同)

Pau*_*ton 5

另一个可能的答案是:

fooboos = foos.stream()
              .flatMap(foo -> generateBoo(foo)
                                  .map(boo -> new FooBoo(foo, boo))
                                  .map(Stream::of)
                                  .orElseGet(Stream::empty)
              ).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我认为在 Java 9 中我们会看到一个stream方法被添加到Optional. 那么我们就可以做到:

fooboos = foos.stream()
              .flatMap(foo -> generateBoo(foo).map(boo -> new FooBoo(foo, boo)).stream())
              .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 为了使其为 Java 9 做好准备,您可以添加一个额外的映射: `.flatMap(foo -&gt;generateBoo(foo).map(boo -&gt; new FooBoo(foo, boo)).map(Stream::of).orElseGet (流::空))` (3认同)
  • 也可以写成 .flatMap(foo -&gt;generateBoo(foo).map(boo -&gt; Stream.of(new FooBoo(foo, boo)).orElseGet(Stream::empty) (2认同)
  • `optical.stream()` 将等同于 `optical.map(Stream::of).orElseGet(Stream::empty)`… (2认同)
  • @PaulBoddington,我很难让我的大脑受 15 年以上命令式编程的影响,使用函数式惯用语进行思考,但它即将到来。你可能会习惯的。 (2认同)