我将尝试简化我面临的情况。有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")]
我设法使用中间列表来解决它,但是我仍然不确定这是最好的解决方案。
我想知道是否可以使用纯流来做类似的事情。我可以使用地图和过滤器,并生成一个大小等于/小于 原始输入,但我不知道如何生成包含更多元素的结果。
答案 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进行操作,只需将faltMap
与map
组合起来
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