Han*_*els 9 java collections foreach java-8 java-stream
我有以下代码:
interface Device {
// ...
boolean isDisconnected();
void reconnect();
}
interface Gateway {
// ...
List<Device> getDevices();
}
...
for (Gateway gateway : gateways) {
for(Device device : gateway.getDevices()){
if(device.isDisconnected()){
device.reconnect();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用Stream API重构代码.我的第一次尝试如下:
gateways
.stream()
.forEach(
gateway -> {
gateway
.getDevices()
.parallelStream()
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect())
;
}
)
;
Run Code Online (Sandbox Code Playgroud)
我不喜欢它,经过一些修改后我最终得到了这段代码:
gateways
.parallelStream()
.map(gateway -> gateway.getDevices().parallelStream())
.map(stream -> stream.filter(device -> device.isDisconnected()))
.forEach(stream -> stream.forEach(device -> device.reconnect()))
;
Run Code Online (Sandbox Code Playgroud)
我的问题是是否有办法避免嵌套forEach.
ETO*_*ETO 16
您应该使用以下代码flatMap来展平流的流map:
gateways
.parallelStream()
.flatMap(gateway -> gateway.getDevices().parallelStream())
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect());
Run Code Online (Sandbox Code Playgroud)
我会通过使用方法引用而不是lambda表达式进一步改进它:
gateways
.parallelStream()
.map(Gateway::getDevices)
.flatMap(List::stream)
.filter(Device::isDisconnected)
.forEach(Device::reconnect);
Run Code Online (Sandbox Code Playgroud)
Mak*_*oto 11
不要将代码重构为使用Streams.你没有获得任何好处,也没有比这样做更有优势,因为现在代码对于未来的维护者来说可读性较差,而且不那么惯用.
通过不使用流,您可以避免使用嵌套forEach语句.
请记住:流是为了更安全的并行化而无副作用. forEach根据定义,引入了副作用.你失去了流的好处并且同时失去了可读性,这使得它根本不那么令人满意.