Joh*_*ler 9 java lambda java-8 java-stream
我正在从丑陋的嵌套for循环转换为java中漂亮的设计lambda表达式.
这是我的实际代码
for (String foo : foos) {
for (Bar bar : bars) {
if (bar.getFoo().equals(foo)) {
FooBar fooBar = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的实际lambda代码替换上面的代码
foos.forEach(i -> bars.stream().filter(p -> p.getFoo().equals(i)).findFirst().ifPresent(p -> {
FooBar s = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
}));
Run Code Online (Sandbox Code Playgroud)
我的问题是,有一种方法可以填充listOfFooBar某种collect()方法吗?
就像是 listOfFooBar = foos.forEach(.....).collect(Collectors.toList());
一个事实是,条形图总是包含每个foo,foos基本上是条形图的一小部分.
如果有更好的方法(在性能或优雅方面)做那个lambda,请分享.
如果你想要整整九码:
List<FooBar> listOfFooBar = foos.stream()
.flatMap(foo -> bars.stream().filter(bar-> bar.getFoo().equals(foo)).findFirst()
.map(Stream::of).orElse(Stream.empty()))
.map(bar -> {
FooBar fooBar = new FooBar();
fooBar.setBar(bar);
return fooBar;
})
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
如果你有一个FooBar接受a 的构造函数,Bar那么你可以保存一些行并写入
.map(FooBar::new)
Run Code Online (Sandbox Code Playgroud)
Java 9中的FWIW您将能够编写
.findFirst().stream()
Run Code Online (Sandbox Code Playgroud)
假设一个合适的构造函数,它将缩短为
List<FooBar> listOfFooBar = foos.stream()
.flatMap(foo -> bars.stream().filter(bar-> bar.getFoo().equals(foo)).findFirst().stream()))
.map(FooBar::new)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
编辑:使用@Misha的建议你可以进一步缩短它:
List<FooBar> listOfFooBar = foos.stream()
.flatMap(foo -> bars.stream().filter(bar-> bar.getFoo().equals(foo)).limit(1)))
.map(FooBar::new)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
由于每个Foo只有一个Bar,你可以从创建一个将Foos连接到Bars的地图开始:
Map<String, Bar> barsByFoo = bars.stream().collect(toMap(Bar::getFoo, b -> b));
Run Code Online (Sandbox Code Playgroud)
如果你有更多的酒吧而不是foos,你可以过滤:
Map<String, Bar> barsByFoo = bars.stream()
.filter(b -> foos.contains(b.getFoo()))
.collect(toMap(Bar::getFoo, b -> b));
Run Code Online (Sandbox Code Playgroud)
然后可以编写嵌套的for循环:
List<FooBar> listOfFooBar = foos.stream()
.map(barsByFoo::get)
.filter(Objects::nonNull)
.map(FooBar::new)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
这假设有一个FooBar(Bar)构造函数.
或者您可以从另一方面解决问题并使用(我认为)等效的算法(Set<Foo>在这种情况下您可能会受益于使用a ):
List<FooBar> listOfFooBar = bars.stream()
.filter(bar -> foos.contains(bar.getFoo()))
.map(FooBar::new)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,它通常有助于退出您的初始循环,因为不同的算法/方法通常有利于干净的lambda解决方案.
| 归档时间: |
|
| 查看次数: |
881 次 |
| 最近记录: |