Объедините два списка на основе данных результатов, чтобы создать новый список в Java 8 - PullRequest
0 голосов
/ 02 июля 2018

Я хочу объединить два списка в один список на основе определенных критериев. Пример списка 1 содержит

final Org ro1= new Org(1, 1001, "Name 01");
final Org ro2 = new Org (2, 1001, "Name 02");
final Org ro3 = new Org (3, 1002, "Name 03");
final Org ro4 = new Org (4, 1003, "Name 04");
final Org ro5 = new Org (5, 1004, "Name 05");
List<Org> listOrg = new ArrayList<>();
// Add all the object to the listOrg 

Список 2 содержит

final Candidate can1 = new Candidate(1001, "Candidate01", "100");
final Candidate can2 = new Candidate(1002, "Candidate02", "150");
final Candidate can3 = new Candidate(1003, "Candidate03", "200");
List<Candidate > listCandidate  = new ArrayList<>();
// Add all the Candidate  object to the listCandidate  

Мой окончательный список будет выглядеть как

List<Result > listResult  = new ArrayList<>();
// Each individual object of the listResult is followed- 
final Result rs1= new Result (1, 1001, "Name 01", "Candidate01", "100");
final Result rs2 = new Result (2, 1001, "Name 02", "Candidate01", "100");
final Result rs3 = new Result (3, 1002, "Name 03", "Candidate02", "150");
final Result rs4 = new Result (4, 1003, "Name 04", "Candidate03", "200");
final Result rs5 = new Result (5, 1004, "Name 05", null, null);

Я хочу добиться того же, используя функции потока Java 8. Может ли кто-нибудь помочь мне в этом?

Детали моего класса

public class Candidate {
    private int canId;
    private String candidateName;
    private String score;
    //Getter setter with constructors.
}

public class Org{
    private int id;
    private int canId;
    private String name;
    //Getter setter with constructors
}

public class Result {
    private int id;
    private int canId;
    private String name;
    private String candidateName;
    private String score;   
    //Getter setter with constructors.
}

У класса Org есть canId, который служит точкой отображения для класса CandidateClass.

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Вы перебираете свой Org, и для каждого вы ищете соответствующий Candidate, если он существует, а затем строите Result из Org и Candidate, конструктор Result(Org o, Candidate c) будет полезно, как вы можете видеть ниже:

Чтобы не повторять listCandidate каждый раз, вы можете подготовить их на карте, чтобы получить их по canId

1. Детализированное решение

Map<Integer, Candidate> candidates = listCandidate.stream()
                      .collect(Collectors.toMap(Candidate::getCanId, Function.identity()));
List<Result > listResult  = new ArrayList<>();
listOrg.forEach(org -> {
          Candidate can = candidates.getOrDefault(ro.getCanId(), null);
          Result r = new Result(org, can);
          listResult.add(r); 
        });

2. Краткое решение с использованием Streams

Map<Integer, Candidate> candidates = listCandidate.stream()
                      .collect(Collectors.toMap(Candidate::getCanId, Function.identity()));

List<Result > listResult = listOrg.stream()
                 .map(org -> new Result(org, candidates.getOrDefault(ro.getCanId(), null)))
                 .collect(Collectors.toList());

3. Result конструктор для добавления

public Result(Org o, Candidate c){
    this.id = org.getId();
    this.canId = org.getCanId();
    this.name = org.getName();
    this.candidateName = c==null ? null : c.getCandidateName(); // return null if c is null
    this.score = c==null ? null : c.getScore());                // return null if c is null
}
0 голосов
/ 02 июля 2018

Вы можете сделать это так,

Map<Integer, Candidate> candidateById = listCandidate.stream()
        .collect(Collectors.toMap(Candidate::getId, Function.identity()));
List<Result> resultList = listOrg.stream()
        .map(o -> {
          Candidate candidate = candidateById.getOrDefault(o.getCandidateId(), new Candidate(-1, null, null));
          return new Result(o.getId(), o.getCandidateId(), o.getName(), candidate.getName(), candidate.getNum());
    })
    .collect(Collectors.toList());

Сначала создайте Map из Candidate объектов по их значению Id. Затем выполните итерацию по List из Org объектов, получите связанный экземпляр Candidate из карты с заданным значением Id и объедините их вместе, чтобы сформировать Result. Наконец соберите все Results в List.

Обновление

Согласно комментарию ниже, это может быть улучшено, как,

List<Result> resultList = listOrg.stream()
        .map(o -> new Result(o, candidateById.get(o.getCandidateId())))
        .collect(Collectors.toList());

Конструктор Result теперь выглядит так:

public Result(Org org, Candidate candidate) {
        super();
        this.orgId = org.getId();
        this.candidateId = org.getCandidateId();
        this.orgName = org.getName();
        this.candidateName = Optional.ofNullable(candidate).map(c -> c.getName()).orElse(null);
        this.candidateNum = Optional.ofNullable(candidate).map(c -> c.getNum()).orElse(null);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...