Search code examples
java-8java-streamcollectors

How to transform list into object based on some conditions using collect?


I want to know if there is way in .toCollect method of streams to transform a list to object as per some conditions. Here is my code. Request class:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ERequest {
    private String id;
    private String cId;
    private int pid;
    private String ind;
}

Response class:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ExpectedResponse {
    private String data1;
    private String data2;
    private String data3;
    
}

Method

public ExpectedResponse getPref(List<ERequest> request) {
        ExpectedResponse expectedResponse = ExpectedResponse.builder().build();

        Predicate<ERequest> isE = p -> (p.getCId().equals("ab")) && (p.getPid() == 1);
        Predicate<ERequest> isS = p -> (p.getCId().equals("cd")) && (p.getPid() == 2);
        Predicate<ERequest> isP = p -> (p.getCId().equals("ef")) && (p.getPid() == 4);

        List<ERequest> res = request.stream()
                .filter(isE.or(isS).or(isP))
                .collect(Collectors.toList());

        for (ERequest r : res) {
            if (r.getCId().equals("ab")) {
                expectedResponse.setData1(r.getInd());
            }
            if (r.getCId().equals("cd")) {
                expectedResponse.setData2(r.getInd());
            }
            if (r.getCId().equals("ef")) {
                expectedResponse.setData3(r.getInd());
            }
        }
        return expectedResponse;
    }

I'm getting a valid/required list in res, but I still have to use for loop to go over that list and extract data according to few conditions and then populate ExpectedResponse. How can I directly transform request into ExpectedResponse ?


Solution

  • You can do all operations while first iteration using filter to filter the records and reduce, This is just an approach using reduce method but i haven't validated since i don't have sample data

     ExpectedResponse expectedResponse = requests.stream().filter(req->(req.getCId().equals("ab")) && (req.getPid() == 1) ||
                (req.getCId().equals("cd")) && (req.getPid() == 2) ||
                (req.getCId().equals("ef")) && (req.getPid() == 4))
                .reduce(ExpectedResponse.builder().build(),(response, request)->{
                    if (request.getCId().equals("ab")) {
                        response.setData1(request.getInd());
                    }
                    if (request.getCId().equals("cd")) {
                        response.setData2(request.getInd());
                    }
                    if (request.getCId().equals("ef")) {
                        response.setData3(request.getInd());
                    }
                    return response;
                },(finalRes,finalReq)->finalRes);