Home > database >  Convert for each loops to stream
Convert for each loops to stream

Time:12-19

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 has commands and attributes objects
  • each command object has members objects
  • each attribute object has fields 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.

  • Related