根据结果​​数据合并两个列表以在Java 8中创建一个新列表

时间:2018-07-02 07:14:09

标签: java collections java-8 java-stream

我想根据某些条件将两个列表合并为一个列表。 示例是列表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 :(得分:2)

您可以这样做

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());

首先根据其ID值创建Map个对象的Candidate。然后,对List个对象的Org进行迭代,从具有给定ID值的映射中获取关联的Candidate实例,并将它们合并在一起以形成一个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);
    }

答案 1 :(得分:1)

您遍历Org,并为每个Candidate寻找相应的Result,然后从Org和{{1 }},构造函数Candidate会很有帮助,如下所示:

为避免每次都迭代Result(Org o, Candidate c),您可以在地图中准备它们,以listCandidate的方式获取它们

1。详细的解决方案

canId

2。。使用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); });

的简短解决方案
Streams

3。 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()); 构造函数添加

Result