仅在另一个集合(带有lambda)的列表中填充其他字段/附加字段

时间:2018-07-31 15:57:42

标签: java java-8 java-stream

我有一个原始集合List<Reviewers>和一个新集合List<ReviewPerson>,其中Reviewers中的某些字段将被复制到ReviewPerson

新列表是以特殊方式构造的,而不是直接从reviewers.stream().map(...)中构造的。但是最后,我需要复制每个bean statuscomments中存在的2个附加列。

List<Reviewers> originalList = ... // from DAO
if (!originalList.isEmpty()) {
   List<ReviewPerson> newList = new ArrayList<ReviewPerson>();

   // this fills out some columns of the ReviewPerson, not all;
   // must use this partial construction from service class
   newList.addAll(service.initialPopulation()); 

   // At the end, need to copy: (1) status, (2) comments
   // ...
}

问题是我做不到,

originalList.stream()
    .map(obj -> new ReviewPerson(obj.getField1(), obj.getField2(), 
                                 // ...
                                 obj.getStatus(), obj.getComments()))
    .collect(Collectors.toList());

因为我没有在集合中构造新对象。我该怎么办?

2 个答案:

答案 0 :(得分:2)

一种常见的解决方案是流式传输列表的(可能是相对应的)索引,并使用相同的索引来访问两个列表:

IntStream.range(0, originalList.size()).forEach(i -> {
    newList.get(i).setFieldA(originalList.get(i).getFieldA();
    newList.get(i).setFieldB(originalList.get(i).getFieldB();
    // etc...
});

但是,老实说,这可能是为了流媒体而流媒体。有时候,一个好的老式直接for循环只是一个更好的解决方案。

答案 1 :(得分:2)

如果您不介意额外的依赖关系,并且如果ReviewerReviewPerson确实是对应的,我建议使用jOOλ库及其{{3} }方法(SeqStream的子类型)和Seq.zip()重载。

使用上面的代码,您可以得到如此简洁的代码:

Seq.zip(newList, originalList).forEach(Tuple.consumer((reviewPerson, reviewer) -> {
    reviewPerson.setStatus(reviewer.getStatus());
    reviewPerson.setComments(reviewer.getComments());
}));