简体   繁体   中英

Getting a map object in form of Map<String, Map<String, List<SalaryMapper>>> from JSON Array

There's a JSON array response I am getting as below.

    [{
        contracted: 1
        payrolltype: basicsalary
        otherdata: sampledata
        salary: 1000
    },{
        contracted: 1
        payrolltype: basicsalary
        otherdata: sampledata
        salary: 1001
    },{
        contracted: 2
        payrolltype: basicsalary
        otherdata: sampledata
        salary: 10002
    },
    {
        contracted: 1
        payrolltype: addon
        otherdata: sampledata
        salary: 1004
    }]

I want to structure this data in the form of Map<String, Map<String,List<SalaryMapper>>>

First, I needed to arrange the data by contractId with the List of Object mapped with the objects where contractId field is common.

For this, I have used java stream as given:

List<SalaryMapper> salMap = myArray;
Map<String, List<SalaryMapper>> map = salMap.stream().collect(Collectors.groupingBy(SalaryMapper::getContractId));

Now I am getting the result grouped by contractId . And I am trying to group the map to another level by payrollType : Map<contractId, Map<payrollType, List<SalaryMapper>>> .

For this, I tried to iterate the main map and push it to Map<contractId, Map<payrollType, List<SalaryMapper>>> object, but I am getting lost here.

    Map<String, Map<String,List<SalaryMapper>>> subMap = null;
            
    Map<String,List<SalaryMapper>> newMapForPayrollType = null;
            
    for(Map.Entry<String, List<SalaryMapper>> entry : map.entrySet()) {
                    
    }
            
    return subMap;

You can do nested level groupingBy by passingdownstream Collector to do a secondary groupingBy

Map<Integer, Map<String, List<SalaryMapper>>> map = salMap.stream()
    .collect(Collectors.groupingBy(SalaryMapper::getContractId,
      Collectors.groupingBy(SalaryMapper::getPayrollType)));

As per the data shown in above the contractid is of Integer type and payrolltype is String , more examples can be found here

The naive approach to your question would be as below:

Map<String, Map<String, List<SalaryMapper>>> subMap = new HashMap<>();        

for (SalaryMapper sal: salMap) {
    Map<String, List<SalaryMapper>> payrollTypeMap = new HashMap<>();
    if (subMap.containsKey(sal.getContractId()) {
        payrollTypeMap = subMap.get(sal.getContractId());
        if (payrollTypeMap.containsKey(sal.getPayrollType())) {
            payrollTypeMap.put(sal.getPayrollType(), payrollTypeMap.get(sal.getPayrollType()).add(sal));
        } else {
           payrollTypeMap.put(sal.getPayrollType(), new ArrayList<>(){{add(sal);}};
        }
    } else {
        payrollTypeMap.put(sal.getPayrollType(), new ArrayList<>(){{add(sal);}};
    }
    subMap.put(sal.getContractId(), payrollTypeMap);
}

Above code can be optimized and written with fewer lines of code as below:

Map<Integer, Map<String, List<SalaryMapper>>> subMap = salMap.stream()
       .collect(Collectors.groupingBy(SalaryMapper::getContractId,
         Collectors.groupingBy(SalaryMapper::getPayrollType)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM