我有这样的结构:
Map<Long, List<Foo>>
类Foo
公开方法:
Class Foo {
public List<Bar> getBars();
public void setBars(List<Bar> bars);
}
现在,我想将此映射转换为List
带有Foo
类的参数,其中该列表中的每个项目都是Foo
具有给定long值的聚合条形列表的实例。例如地图:
{1: [Foo1, Foo2],
2: [Foo3]}
在哪里
Foo1.bars = [Bar1, Bar2]
Foo2.bars = [Bar3]
Foo3.bars = [Bar4, Bar5]
我想得到的结果是:
[FooA, FooB]
在哪里
FooA.bars = [Bar1, Bar2, Bar3]
FooB.bars = [Bar4, Bar5]
在Java 8中,最完美的解决方案是什么?Foo
必要时可以重用map中的某些实例,因为此操作后不再使用它们。
假设您有一个Foo(List<Bar> bars)
构造函数,这很简单:
import static java.util.stream.Collectors.*;
List<Foo> result = map.values()
.stream()
.map(
foos -> new Foo(foos.stream()
.flatMap(foo -> foo.getBars().stream())
.collect(toList())))
.collect(toList());
我们采用原始地图值(我们不在乎键)的流,这些值是的列表Foo
。我们展平每个这样的列表以获取的流Bar
,将它们收集到列表中并将该列表传递给Foo(List<Bar>)
构造函数,以便获得新的Foo
对象。最后,我们将它们收集到List
。
如果没有Foo(List<Bar>)
唯一的setter,则应首先创建一个empty Foo
,然后使用setter并返回创建的Foo
:
List<Foo> result = map.values()
.stream()
.map(foos -> {
Foo f = new Foo();
f.setBars(foos.stream().flatMap(
foo -> foo.getBars().stream()).collect(toList()));
return f;
})
.collect(toList());
如果您不想创建新Foo
对象(例如,要保留其他属性),则最好不引入setBars
,而是addBars
方法(将新的条形添加到现有的条形),如下所示:
public class Foo {
...
public Foo addBars(List<Bar> bars) {
this.bars.addAll(bars);
return this;
}
}
现在,您可以使用reduce
终端操作来组合foos:
List<Foo> result = map.values()
.stream()
.map(foos -> foos.stream()
.reduce((foo1, foo2) -> foo1.addBars(foo2.getBars())).get())
.collect(toList());
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句