简体   繁体   中英

Java 8 Stream add new object to list from return value

I want to save the return value of a method and use it to create a new object with which ill add to a list. Here is the block of code for more clarity:

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()));
    }
}

I've tried something like this:

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

But obviously I'm missing something here which is actuallying creating the FooBoo object. How exactly do I do that with the java stream method?

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

Another possible answer is:

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

I think in Java 9 we will see a stream method added to Optional . Then we will be able to do:

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

You need to hold on too the Foo , but you lose it when you map it to the result of generateBoo . If you have some kind of Pair or Tuple so that you can map both the Foo and the Boo into one object, you can then later combine them. I've seen some people use an array of two objects and AbstractMap.SimpleImmutableEntry as a quick and dirty Pair equivalent, both of which are awkward. Whether you use something existing or create your own simple Pair object, without questioning the wisdom of using Optional in this case, you might do this:

fooboos = foos
        .stream()
        .map(f -> new Pair(f, generateBoo(f))
        .filter(p -> p.getV2().isPresent())
        .map(p -> new Pair(p.getV1(), p.getV2().get())
        .map(p -> new Fooboo(p.getV1(), p.getV2()))
        .collect(Collectors.toList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM