sla*_*omy 3 java algorithm java-8
我有这样的结构:
Map<Long, List<Foo>>
Run Code Online (Sandbox Code Playgroud)
class Foo暴露方法的地方:
Class Foo {
public List<Bar> getBars();
public void setBars(List<Bar> bars);
}
Run Code Online (Sandbox Code Playgroud)
现在我想将此映射转换为List使用Foo类进行参数化,其中此列表中的每个项都是Foo具有给定长值的聚合条列表的实例.例如,使用地图:
{1: [Foo1, Foo2],
2: [Foo3]}
Run Code Online (Sandbox Code Playgroud)
哪里
Foo1.bars = [Bar1, Bar2]
Foo2.bars = [Bar3]
Foo3.bars = [Bar4, Bar5]
Run Code Online (Sandbox Code Playgroud)
我想得到的结果是:
[FooA, FooB]
Run Code Online (Sandbox Code Playgroud)
哪里
FooA.bars = [Bar1, Bar2, Bar3]
FooB.bars = [Bar4, Bar5]
Run Code Online (Sandbox Code Playgroud)
在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());
Run Code Online (Sandbox Code Playgroud)
我们采用原始地图值的流(我们不关心密钥),它们是列表Foo.我们将每个这样的列表展平以获取流Bar,将它们收集到列表中并将此列表传递给Foo(List<Bar>)构造函数,以便我们获得新Foo对象.最后我们将它们收集到List.
如果你没有Foo(List<Bar>),只有setter,你应该先创建一个空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());
Run Code Online (Sandbox Code Playgroud)
如果你不想创建新Foo对象(例如,你想要保留其他属性),最好不要引入setBars,而是引入addBars方法(为现有的方法添加新的条形图),如下所示:
public class Foo {
...
public Foo addBars(List<Bar> bars) {
this.bars.addAll(bars);
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用reduce终端操作来组合foos:
List<Foo> result = map.values()
.stream()
.map(foos -> foos.stream()
.reduce((foo1, foo2) -> foo1.addBars(foo2.getBars())).get())
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
124 次 |
| 最近记录: |