Home > Blockchain >  SpringBoot / Java : How to count Item and get the result in an object Map<String,Map<String, M
SpringBoot / Java : How to count Item and get the result in an object Map<String,Map<String, M

Time:10-25

Really new in SpringBoot environment and not familiar with all the annotations and methods.

My problem is quite easy but I'm totally stuck. I have a Table Device with some columns such as Type, Constructor, Model.

I would like to count the number of devices by Model for each Constructor and Type and return a Map all those in the following format :

"numberOfDevicePerTypeConstructorModel": {
    "Type1": {
         "Constructor1": {
            "Model1": 0,
            "Model2": 0,
         },
         "Constructor2": {
            "Model1": 0,
            "Model2": 0,
         }
    },
    "Type2": {
         "Constructor1": {
            "Model1": 0,
            "Model2": 0,
         },
        "Category2": {
            "Model1": 0,
            "Model2": 0,
        }
    },
}

For Example, I could make an easy one to get a simple Map<String, Long> of the number of Device by model like this :

        for (String model : deviceRepository.findDistinctModel()) {
            deviceStats.numberOfDevicePerModel.put(model, deviceRepository.countByModel(model));
        }

But if now I try to imbricate some "for loop" on Type and Constructor and make some intermediary Map<String, Long> it doesn't really work.

public class DeviceService() {
        public class DeviceStats() {

                public Map<String,Long> numberPerModel;    
                public Map<String,Map<String,Long>> numberPerConstructorModel;   
                public Map<String, Map<String,Map<String,Long>>> numberOfDevicePerTypeConstructorModel;

                DeviceStats(){
                    numberPerModel = new HashMap<String,Long>();    
                    numberPerConstructorModel = new HashMap<String,Map<String,Long>>();
                    numberOfDevicePerTypeConstructorModel = new HashMap<String,Map<String,Map<String,Long>>>();
                }
       }


        public DeviceStats getDeviceStats() {
            for(String type :  deviceRepository.findDistinctType()) {   
                for(String constructor : deviceRepository.findDistinctConstructorByType(type)){
                    for (String model : deviceRepository.findDistinctModelByTypeAndConstructor(type,constructor)) { 
                        deviceStats.numberPerModel.put(model, deviceRepository.countByModelAndConstructorAndType(model, constructor,type));
                    }
                    deviceStats.numberPerConstructorModel.put(constructor, deviceStats.numberPerModel);
                }
                deviceStats.numberOfDevicePerTypeConstructorModel.put(type, deviceStats.numberPerConstructorModel);
           }
       }
}

Hope I've been clear. Thank you for your help or advice on how to do that easily. (I'm sure it can be done within a couple of lines of code but I don't see how.)

Thanks

CodePudding user response:

If I may preach here a little bit: I don't think is a good idea to make db calls in a for loop. Maybe it would be better if you first constructed your query in a way that suits you so, before processing, you end up having a List<DeviceStat> deviceStats and then:

public static Map<String, Map<String, Map<String, Long>>> getDeviceStats(List<DeviceStat> deviceStats) {
       return deviceStats.stream()
            .collect(Collectors.groupingBy(DeviceStat::getType,
                 Collectors.groupingBy(DeviceStat::getConstructor,
                    Collectors.groupingBy(DeviceStat::getModel, 
                    Collectors.counting()))));
} 

CodePudding user response:

I don't think you need embeded class. You need something like:

public class DeviceService() {

    public Map<String, Map<String, Map<String, Long>>> getDeviceStats() {
        Map<String, Map<String, Map<String, Long>>> numberOfDevicePerTypeConstructorModel =
                new HashMap<String, Map<String, Map<String, Long>>>();
        for (String type : deviceRepository.findDistinctType()) {
            Map<String, Map<String, Long>> numberPerConstructorModel = new HashMap<String, Map<String, Long>>();
            numberOfDevicePerTypeConstructorModel.put(type, numberPerConstructorModel);
            for (String constructor : deviceRepository.findDistinctConstructorByType(type)) {
                Map<String, Long> numberPerModel = new HashMap<String, Long>();
                numberPerConstructorModel.put(constructor, numberPerModel);
                for (String model : deviceRepository.findDistinctModelByTypeAndConstructor(type, constructor)) {
                    numberPerModel.put(model, deviceRepository.countByModelAndConstructorAndType(model, constructor, type));
                }
            }
        }
        return  numberOfDevicePerTypeConstructorModel;
    }
}
  • Related