流可以创建新对象吗?

时间:2019-09-19 19:17:05

标签: java java-8 java-stream

我将尝试简化我面临的情况。有2个实体:

class Foo {
    String fooProperty;

    @OneToOne
    Bar bar;
}

class Bar {
    String barProperty;
}

还有一个具有Foo和Bar属性的DTO类:

class FooDto {
    String fooProperty;
    String barProperty;

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

FooDto用于传递大量数据,并且可以使用流轻松完成转换:

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

现在,需求发生了变化,并且Foo可以有很多Bar:

@OneToMany
List<Bar> bar;

还要求应该为每个包含Bar的对象生成一个FooDto,如下所示:

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

将转换为:

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

我设法使用中间列表来解决它,但是我仍然不确定这是最好的解决方案。

我想知道是否可以使用纯流来做类似的事情。我可以使用地图和过滤器,并生成一个大小等于/小于 原始输入,但我不知道如何生成包含更多元素的结果。

2 个答案:

答案 0 :(得分:3)

您要查找的操作称为flatMap

它对Foo个对象流进行操作,以将Foo对象转换为FooDto个对象流并返回{{1 }}对象:

FooDto

然后:

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

答案 1 :(得分:0)

是的,可以通过Streams进行操作,只需将faltMapmap组合起来

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Foo {
    String fooProperty;
    List<Bar> bars;

    public Foo(String fooProperty, List<Bar> bars) {
        this.fooProperty = fooProperty;
        this.bars = bars;
    }
}

class Bar {
    String barProperty;

    public Bar(String barProperty) {
        this.barProperty = barProperty;
    }
}

class FooDto {
    String fooProperty;
    String barProperty;

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

    public static List<FooDto> from(List<Foo> foos) {
        return foos.stream().
                            flatMap(foo -> foo.bars.stream().
                                    map(bar -> new FooDto(foo.fooProperty, bar.barProperty))).
                            collect(Collectors.toList());
    }


}

例如:

public static void main(String[] args) {
    Bar b1 = new Bar("b1");
    Bar b2 = new Bar("b2");
    Bar b3 = new Bar("b3");
    Bar b4 = new Bar("b4");

    Foo foo = new Foo("Foo 1", Arrays.asList(b1,b2));
    Foo foo2 = new Foo("Foo 2", Arrays.asList(b2,b3,b4));
    List<FooDto> result = FooDto.from(Arrays.asList(foo, foo2));
    result.forEach(f -> System.out.println(f.fooProperty + ": " + f.barProperty));
}
  

输出

Foo 1: b1
Foo 1: b2
Foo 2: b2
Foo 2: b3
Foo 2: b4