Search code examples
javaspringjpaspring-data-jpajava-stream

Stream API convert entity to JSON


I have a list of Entity which I got from repository.

[DataEntity(key=0a3e1588-ad59-3586-b071-d5001f5ff9a7, timestamp=2024-05-24 09:48:00.0, value=10.0),
DataEntity(key=0a3e1588-ad59-3586-b071-d5001f5ff9a7, timestamp=2024-05-24 09:46:00.0, value=11.0),
DataEntity(key=0a3e1588-ad59-3586-b071-d5001f5ff9a7, timestamp=2024-05-24 09:44:00.0, value=12.0),

DataEntity(key=b349f0ea-c810-3790-bdc3-a82ed5921a28, timestamp=2024-05-24 09:48:00.0, value=13.0),
DataEntity(key=b349f0ea-c810-3790-bdc3-a82ed5921a28, timestamp=2024-05-24 09:46:00.0, value=14.0),
DataEntity(key=b349f0ea-c810-3790-bdc3-a82ed5921a28, timestamp=2024-05-24 09:44:00.0, value=15.0),

DataEntity(key=63d29aeb-ab91-3d24-b40c-d69f2955a893, timestamp=2024-05-24 09:48:00.0, value=16.0),
DataEntity(key=63d29aeb-ab91-3d24-b40c-d69f2955a893, timestamp=2024-05-24 09:46:00.0, value=17.0),
DataEntity(key=63d29aeb-ab91-3d24-b40c-d69f2955a893, timestamp=2024-05-24 09:44:00.0, value=18.0)]

I don't know how to implement this is stream api way. I want to convert this list into JSON using Stream API. Does it make sense to use parallel stream or in my case, ordinary stream will be enough? This is the expected structure:

{
    "0a3e1588-ad59-3586-b071-d5001f5ff9a7": [
        {
            "timestamp" : "2024-05-24 09:48:00.0",
            "value" : 10.0
        },
        {
            "timestamp" : "2024-05-24 09:46:00.0",
            "value" : 11.0
        }
        {
            "timestamp" : "2024-05-24 09:44:00.0",
            "value" : 12.0
        }
    ],

    "b349f0ea-c810-3790-bdc3-a82ed5921a28": [
        {
            "timestamp" : "2024-05-24 09:48:00.0",
            "value" : 13.0
        },
        {
            "timestamp" : "2024-05-24 09:46:00.0",
            "value" : 14.0
        }
        {
            "timestamp" : "2024-05-24 09:44:00.0",
            "value" : 15.0
        }
    ],

    "63d29aeb-ab91-3d24-b40c-d69f2955a893": [
        {
            "timestamp" : "2024-05-24 09:48:00.0",
            "value" : 16.0
        },
        {
            "timestamp" : "2024-05-24 09:46:00.0",
            "value" : 17.0
        }
        {
            "timestamp" : "2024-05-24 09:44:00.0",
            "value" : 18.0
        }
    ]

}

This is my implementation in ordinary style, but it looks ugly. How can I implement this using Stream API.

            List<DataEntity> dataEntityList = repository.getRecordCountForPeriod();

            Map response = new HashMap();
            for (DataEntity data : dataEntityList) {
                if(response.containsKey(data.getKey())){

                    List list = (List) response.get(data.getKey());
                    Map map = new HashMap<>();
                    map.put("timestamp", data.getTimestamp());
                    map.put("value", data.getInstancesValue());
                    list.add(map);

                }else{
                    List list = new ArrayList();
                    Map map = new HashMap<>();
                    map.put("timestamp", data.getTimestamp());
                    map.put("value", data.getInstancesValue());
                    list.add(map);
                    response.put(data.getKey(), list);
                }
            }

Solution

  • Here is the working solution for your problem, created a DataRecord class that holds timestamp and value as field:

            List<DataEntity> list = List.of(
                    new DataEntity("0a3e1588-ad59-3586-b071-d5001f5ff9a7", "2024-05-24 09:48:00.0", 10.0),
                    new DataEntity("0a3e1588-ad59-3586-b071-d5001f5ff9a7", "2024-05-24 09:46:00.0", 11.0),
                    new DataEntity("0a3e1588-ad59-3586-b071-d5001f5ff9a7", "2024-05-24 09:44:00.0", 12.0),
        
                    new DataEntity("b349f0ea-c810-3790-bdc3-a82ed5921a28", "2024-05-24 09:48:00.0", 13.0),
                    new DataEntity("b349f0ea-c810-3790-bdc3-a82ed5921a28", "2024-05-24 09:46:00.0", 14.0),
                    new DataEntity("b349f0ea-c810-3790-bdc3-a82ed5921a28", "2024-05-24 09:44:00.0", 15.0),
        
                    new DataEntity("63d29aeb-ab91-3d24-b40c-d69f2955a893", "2024-05-24 09:48:00.0", 16.0),
                    new DataEntity("63d29aeb-ab91-3d24-b40c-d69f2955a893", "2024-05-24 09:46:00.0", 17.0),
                    new DataEntity("63d29aeb-ab91-3d24-b40c-d69f2955a893", "2024-05-24 09:44:00.0", 18.0));
        
            Map<String, List<DataRecord>> map = Optional.ofNullable(list).orElse(Collections.emptyList()).stream()
                    .collect(Collectors.groupingBy(DataEntity::getKey,
                            Collectors.mapping(
                                    dataEntity -> new DataRecord(dataEntity.getTimestamp(), dataEntity.getValue()),
                                    Collectors.toList())));
        
            System.out.println(map);
            //output
    //      {0a3e1588-ad59-3586-b071-d5001f5ff9a7=[DataRecord [timestamp=2024-05-24 09:48:00.0, value=10.0], 
    //                                             DataRecord [timestamp=2024-05-24 09:46:00.0, value=11.0], 
    //                                             DataRecord [timestamp=2024-05-24 09:44:00.0, value=12.0]], 
    //      63d29aeb-ab91-3d24-b40c-d69f2955a893=[DataRecord [timestamp=2024-05-24 09:48:00.0, value=16.0], 
    //                                            DataRecord [timestamp=2024-05-24 09:46:00.0, value=17.0], 
    //                                            DataRecord [timestamp=2024-05-24 09:44:00.0, value=18.0]], 
    //      b349f0ea-c810-3790-bdc3-a82ed5921a28=[DataRecord [timestamp=2024-05-24 09:48:00.0, value=13.0], 
    //                                            DataRecord [timestamp=2024-05-24 09:46:00.0, value=14.0], 
    //                                            DataRecord [timestamp=2024-05-24 09:44:00.0, value=15.0]]}
        
        public class DataRecord {
        
            private String timestamp;
            private double value;
        
            public DataRecord(String timestamp, double value) {
                super();
                this.timestamp = timestamp;
                this.value = value;
            }
        }