3

I have a list of objects of structure

public class SimpleObject {
    private TypeEnum type;
    private String propA;
    private Integer propB;
    private String propC;
}

which I would like to "pack" into the following objects

public class ComplexObject {
    private TypeEnum type;
    private List<SimpleObject> simpleObjects;
}

based on TypeEnum.
In other words I'd like to create a sort of aggregations which will hold every SimpleObject that contains a certain type. I thought of doing it with Java 8 streams but I don't know how.

So let's say I'm getting the list of SimpleObjects like

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DataService {
    private final DataRepository dataRepo;

    public void getPackedData() {
        dataRepo.getSimpleObjects().stream()...
    }

}

How the next steps should look like? Thank you in advance for any help

I'm using Java 14 with Spring Boot

Naman
  • 27,789
  • 26
  • 218
  • 353
big_OS
  • 381
  • 7
  • 20
  • Does this answer your question? [Partition a Java 8 Stream](https://stackoverflow.com/questions/32434592/partition-a-java-8-stream) – OrangeDog Oct 30 '20 at 12:27

2 Answers2

2

You can use Collectors.groupingBy to group by type which return Map<TypeEnum, List<SimpleObject>>. Then again stream over map's entryset to convert into List<ComplexObject>

List<ComplexObject> res = 
     dataRepo.getSimpleObjects()
        .stream()
        .collect(Collectors.groupingBy(SimpleObject::getType)) //Map<TypeEnum, List<SimpleObject>>
        .entrySet()
        .stream()
        .map(e -> new ComplexObject(e.getKey(), e.getValue()))  // ...Stream<ComplexObject>
        .collect(Collectors.toList());
Eklavya
  • 17,618
  • 4
  • 28
  • 57
1

You can achieve this with Collectors.groupingBy and further conversion of entries to a list of objects using Collectors.collectingAndThen.

List<SimpleObject> list = ...
List<ComplexObject> map = list.stream()
   .collect(Collectors.collectingAndThen(
       Collectors.groupingBy(SimpleObject::getType),                // group by TypeEnum
          map -> map.entrySet()                                     // map entries to ..
             .stream()
             .map(e -> new ComplexObject(e.getKey(), e.getValue())) // .. ComplexObject
             .collect(Collectors.toList())));                       // .. to List

I am not currently aware of another solution as long as Stream API is not friendly in processing dictionary structures.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183