I try to convert some for each loops to streams.
I have following object relations:
- the main object is a collection of
sensors
- each
sensor
hascommands
andattributes
objects - each
command
object hasmembers
objects - each
attribute
object hasfields
objects
5 Loops
List<SensorDTO> sensorDTOS = new ArrayList();
// Loop 1
for (Sensor sensor: sensors) {
Set<CommandDTO> commandSet = new HashSet<>();
// Loop 2
for (Command c : sensor.getCommands()) {
Set<MemberDTO> memberSet = new HashSet<>();
// Loop 3
for (Member m : c.getMembers()) {
memberSet.add(new MemberDTO(m.getName()));
}
commandSet.add(new CommandDTO(c.getName(),memberSet));
}
Set<AttributeDTO> attributeSet = new HashSet<>();
// Loop 4
for (Attribute a : sensor.getAttributes()) {
Set<FieldDTO> fieldSet = new HashSet<>();
// Loop 5
for (Field f : a.getFields()) {
fieldSet.add(new FieldDTO(f.getName()));
}
attributeSet.add(new AttributeDTO( a.getName(), fieldSet));
}
SensorDTO sensorDTO = new SensorDTO(attributeSet, commandSet);
sensorDTOS.add(sensorDTO);
}
Attempt using stream().forEach
The only I have accomplished is to print the inner object.
sensors.stream()
.forEach(s-> {
s.getCommands().stream().forEach( c -> {
c.getMembers().stream().forEach( m -> {
System.out.println(m);
});
});
});
How to make a list of sensors
to return as a list of sensorDTOS
?
CodePudding user response:
List<SensorDTO> sensorDTOS = sensors.stream()
.map(sensor -> {
Set<CommandDTO> commandSet = sensor.getCommands().stream()
.map(command -> {
Set<MemberDTO> memberSet = command.getMembers().stream()
.map(member -> new MemberDTO(member.getName()))
.collect(Collectors.toSet());
return new CommandDTO(command.getName(), memberSet);
})
.collect(Collectors.toSet());
Set<AttributeDTO> attributeSet = sensor.getAttributes().stream()
.map(attribute -> {
Set<FieldDTO> fieldSet = attribute.getFields().stream()
.map(field -> new FieldDTO(field.getName()))
.collect(Collectors.toSet());
return new AttributeDTO(attribute.getName(), fieldSet);
})
.collect(Collectors.toSet());
return new SensorDTO(attributeSet, commandSet);
})
.collect(Collectors.toList());
CodePudding user response:
To convert your code to use streams, you can start by replacing the outermost loop with a call to map, which will allow you to transform each Sensor object into a SensorDTO object. You can then use the collect method to collect the results into a list:
List<SensorDTO> sensorDTOS = sensors.stream()
.map(sensor -> {
// Create a set of CommandDTO objects for this sensor
Set<CommandDTO> commandSet = sensor.getCommands().stream()
.map(c -> {
// Create a set of MemberDTO objects for this command
Set<MemberDTO> memberSet = c.getMembers().stream()
.map(m -> new MemberDTO(m.getName()))
.collect(Collectors.toSet());
// Return a new CommandDTO object
return new CommandDTO(c.getName(), memberSet);
})
.collect(Collectors.toSet());
// Create a set of AttributeDTO objects for this sensor
Set<AttributeDTO> attributeSet = sensor.getAttributes().stream()
.map(a -> {
// Create a set of FieldDTO objects for this attribute
Set<FieldDTO> fieldSet = a.getFields().stream()
.map(f -> new FieldDTO(f.getName()))
.collect(Collectors.toSet());
// Return a new AttributeDTO object
return new AttributeDTO(a.getName(), fieldSet);
})
.collect(Collectors.toSet());
// Return a new SensorDTO object
return new SensorDTO(attributeSet, commandSet);
})
.collect(Collectors.toList());
This code should produce the same result as your original code, but it uses streams and functional programming techniques to iterate over the nested collections and create the SensorDTO objects.