Can a stream create new objects?

marcellorvalle :

I will try to simplify a situation I am facing. There are 2 entities:

class Foo {
    String fooProperty;

    @OneToOne
    Bar bar;
}

class Bar {
    String barProperty;
}

There is also a DTO class with the attributes from Foo and Bar:

class FooDto {
    String fooProperty;
    String barProperty;

    public static FooDto from(Foo foo) {
        return new FooDto(foo.fooProperty, foo.bar.barProperty);
    }
}

FooDto is used to deliver huge amounts of data and the conversion can easily be done using streams:

fooList.stream().map(FooDto::from).(...)

Now, there is a change in requirements and a Foo can have many Bars:

@OneToMany
List<Bar> bar;

It is also required that it should be generated one FooDto for each containing Bar, like so:

Foo(fooProperty="foo1", bar=[Bar(barProperty="bar1"), Bar(barProperty="bar2")])

will be converted to:

[FooDto(fooProperty="foo1", barProperty="bar1"), FooDto(fooProperty="foo1", barProperty="bar2")]

I managed to solve it using a intermediate list but I am still unsure it was the best solution.

I was wondering if it is possible to do something like that using purely streams. I can use maps and filters and generate a result with a equal/smaller size than the original input but I can't figure out how to generate a result with more elements.

Thomas Kläger :

The operation that you are looking for is called flatMap.

It operates on a stream of Foo objects, takes as argument a function that converts a Foo object into a stream of FooDto objects and returns a stream combined stream of FooDto objects:

class FooDto {
    String fooProperty;
    String barProperty;

    public FooDto(String fooProperty, String barProperty) {
        this.fooProperty = fooProperty;
        this.barProperty = barProperty;
    }

    public static Stream<FooDto> from(Foo foo) {
        return foo.bars.stream().map(bar -> new FooDto(foo.fooProperty, bar.barProperty));
    }
}

and then:

List<FooDto> result = fooList.stream().flatMap(FooDto::from).(Collectors.toList());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=164260&siteId=1