Hans van Kessels :
I have the following code:
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();
}
}
}
I want to refactor the code using Stream API. My first attempt was like the following:
gateways
.stream()
.forEach(
gateway -> {
gateway
.getDevices()
.parallelStream()
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect())
;
}
)
;
I didn't like it so after some modifications I ended up with this code:
gateways
.parallelStream()
.map(gateway -> gateway.getDevices().parallelStream())
.map(stream -> stream.filter(device -> device.isDisconnected()))
.forEach(stream -> stream.forEach(device -> device.reconnect()))
;
My question is whether there is a way to avoid nested forEach
.
ETO :
You should flatten the stream of streams using flatMap
instead of map
:
gateways
.parallelStream()
.flatMap(gateway -> gateway.getDevices().parallelStream())
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect());
I would improve it further by using method references instead of lambda expressions:
gateways
.parallelStream()
.map(Gateway::getDevices)
.flatMap(List::stream)
.filter(Device::isDisconnected)
.forEach(Device::reconnect);