Home > OS >  How to group a List of records by fields into an Object with Lists inside
How to group a List of records by fields into an Object with Lists inside

Time:05-30

I've tried to figure out how to do this but i'm stuck and i would like some help.

After having done a complex SQL Query and having assigned its result to a JPA Entity that maps this query result as if it was a view, i have this List, where each entry is of the kind (the List of these records is called resultList):

rowId, cf, c1, c2, dt, sx rsd, id_c, cost, gest, idImp, descImp, costImp, idPren, descPren

1, XXXXX, C1, C2, DT, SX, RSD, ID_C, COST, GEST, IDIMP1, DESCIMP1, COSTIMP1, IDPREN1_1, DESCPREN1_1

2, XXXXX, C1, C2, DT, SX, RSD, ID_C, COST, GEST, IDIMP1, DESCIMP1, COSTIMP1, IDPREN1_2, DESCPREN1_2

3, XXXXX, C1, C2, DT, SX, RSD, ID_C, COST, GEST, IDIMP2, DESCIMP1, COSTIMP1, IDPREN2_1, DESCPREN2_1

All the fields before idImp are, because of the query, always the same. I'm trying to gather all these records into an object of class ResultContainerGrouped, which has Lists for the variable elements. So the 3 entries would became:

XXXXX, C1, C2, DT, SX, RSD, ID_C, COST, GEST, { [IDIMP1, DESCIMP1, COSTIMP1 {[IDPREN1_1, DESCPREN1_1], [IDPREN1_2, DESCPREN1_2]} ], [IDIMP2, DESCIMP1, COSTIMP1 { [ IDPREN2_1, DESCPREN2_1 ] } ] }

public class ResultContainerGrouped{
    protected String cf;
    protected String c1;
    protected String c2;
    protected String dt;
    protected String sx;
    protected String rsd;
    protected String id_c;
    protected String cost;
    protected String gest;
    protected List<Imp> listR;
}



public class Imp{
    protected String idImp;
    protected String descImp;
    protected String costImp;
    protected List<Pren> listP;
}



public class Pren{
    protected String idPren;
    protected String descPren;
}



public class ResultContainerRecords{
        protected String cf;
        protected String c1;
        protected String c2;
        protected String dt;
        protected String sx;
        protected String rsd;
        protected String id_c;
        protected String cost;
        protected String gest;
        // represents List<Imp> listR;
        protected String idImp;
        protected String descImp;
        protected String costImp;
        // represents List<Pren> listP;
        protected String idPren;
        protected String descPren;
    }

I had thought to use streams (I am not familiar with stream and i'm trying to getting used to it), but i don't know if it's fitting given that i have different keys (I should groupBy first for idImp, then for idPren?)

I actually got to groupBy idImp, but i don't know how to do with the other list inside idImp.

I set the static values with:

resultContainerGrouped.setCf(resultList.get(0).getCf())
...

then i used stream to group by the ListR, but i don't know how to work with ListP inside ListR.

Map<String, List<ResultContainerRecords>> mapR = resultList.stream()
            .collect(Collectors.groupingBy(ResultContainerRecords::idImp));
            
mapR.values().stream().forEach(x -> resultContainerGrouped.getListR().add(buildR(x)));
            

where buildR is a method used to create a List for each mapR value to responseGrouped's ListR

private ListR buildR (List<ResultContainerRecords> x) {
ListR result = new ListR();

result.setCostImp(x.get(0).getCostImp());
result.setIdImp(x.get(0).getIdImp());
if ((!StringUtils.isEmpty(x.get(0).getDescImp())))
    result.setDescImp(x.get(0).getDescImp());

return result;
}

Any help is much appreciated, thanks!

CodePudding user response:

The solution was to group again, inside the method where i would build objects from the records.

Map<String, List<ResultContainerRecords>> mapR = resultList.stream()
            .collect(Collectors.groupingBy(ResultContainerRecords::idImp));
            
mapR.values().stream().forEach(x -> resultContainerGrouped.getListR().add(buildR(x)));

with buildR being

private ListR buildR (List<ResultContainerRecords> x) {  
ListR result = new ListR();
List<ListP> listP = new ArrayList<>();

result.setCostImp(x.get(0).getCostImp());
result.setIdImp(x.get(0).getIdImp());
if ((!StringUtils.isEmpty(x.get(0).getDescImp())))   result.setDescImp(x.get(0).getDescImp());

Map<String, List< ResultContainerRecords >> mapR = x.stream().collect(Collectors.groupingBy(ResultContainerRecords::getIdPren)); 
mapR.values().stream().forEach(y -> result.getListP().add(buildP(y)));

result.getListP().addAll(listP);

return result;
}

Lastly buildP, for Pren

private ListP buildP (List< ResultContainerRecords > y) {
        ListPr result = new ListP();

        result.setIdPren(z.get(0).getIdPren());
        result.setDescPren(z.get(0).getDescPren());

        return result;
    }
  • Related