#java-8 #java-stream #collectors
Вопрос:
Я хочу знать, есть ли способ в методе .toCollect потоков преобразовать список в объект в соответствии с некоторыми условиями. Вот мой код. Класс запроса:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ERequest {
private String id;
private String cId;
private int pid;
private String ind;
}
Класс ответов:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ExpectedResponse {
private String data1;
private String data2;
private String data3;
}
Метод
public ExpectedResponse getPref(List<ERequest> request) {
ExpectedResponse expectedResponse = ExpectedResponse.builder().build();
Predicate<ERequest> isE = p -> (p.getCId().equals("ab")) amp;amp; (p.getPid() == 1);
Predicate<ERequest> isS = p -> (p.getCId().equals("cd")) amp;amp; (p.getPid() == 2);
Predicate<ERequest> isP = p -> (p.getCId().equals("ef")) amp;amp; (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;
}
Я получаю действительный/требуемый список в res, но мне все равно нужно использовать цикл for, чтобы просмотреть этот список и извлечь данные в соответствии с несколькими условиями, а затем заполнить ожидаемый ответ. Как я могу напрямую преобразовать запрос в ожидаемый ответ ?
Комментарии:
1.
public ExpectedResponse getPref(List<ERequest> request) { ExpectedResponse expectedResponse = ExpectedResponse.builder().build(); for(ERequest r: request) { switch(r.getPid()) { case 1: if (r.getCId().equals("ab")) expectedResponse.setData1(r.getInd()); break; case 2: if (r.getCId().equals("cd")) expectedResponse.setData2(r.getInd()); break; case 4: if (r.getCId().equals("ef")) expectedResponse.setData3(r.getInd()); } } return expectedResponse; }
Ответ №1:
Вы можете выполнять все операции во время первой итерации, используя фильтр для фильтрации записей и уменьшения, это просто подход с использованием reduce
метода, но я не проверял, так как у меня нет образцов данных
ExpectedResponse expectedResponse = requests.stream().filter(req->(req.getCId().equals("ab")) amp;amp; (req.getPid() == 1) ||
(req.getCId().equals("cd")) amp;amp; (req.getPid() == 2) ||
(req.getCId().equals("ef")) amp;amp; (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);