英文:
Use parallel stream in array list with original order
问题
我有一个产品,我想用相同的原始顺序在另一个数组中填充产品,我使用了并行流,但结果与原始顺序不一致。
List<Product> products = productList.getProducts();
List<ProductModelDTOV2> productModelDTOV2s = new ArrayList<>();
products.parallelStream().forEach(p -> {
try {
ProductModelDTOV2 productModelDTOV2 = dtoFactoryV2.populate(p, summary);
productModelDTOV2s.add(productModelDTOV2);
} catch (GenericException e) {
log.debug(String.format("无法填充产品 %s", p));
}
});
return productModelDTOV2s;
英文:
I have a product, I wanna populate products in another array with the same original order, I used parallel Stream and the result was not ordered with the original order
List<Product> products = productList.getProducts();
List<ProductModelDTOV2> productModelDTOV2s = new ArrayList<>();
products.parallelStream().forEach(p -> {
try {
ProductModelDTOV2 ProductModelDTOV2 = dtoFactoryV2.populate(p, summary);
productModelDTOV2s.add(ProductModelDTOV2);
} catch (GenericException e) {
log.debug(String.format("Unable to populate Product %s", p));
}
});
return productModelDTOV2s;
答案1
得分: 5
似乎代码的这一部分可以是无序的并且可以并行运行:
ProductModelDTOV2 ProductModelDTOV2 = dtoFactoryV2.populate(p, summary);
但这部分必须是有序的:
productModelDTOV2s.add(ProductModelDTOV2);
你可以将这两部分分开处理。在 flatMap
中处理第一部分,在 forEachOrdered
中处理第二部分:
products.parallelStream().flatMap(o -> { // 这个块将会并行处理
try {
return Stream.of(dtoFactoryV2.populate(p, summary));
} catch (GenericException e) {
// 不要期望这条信息会按顺序打印
log.debug(String.format("无法填充产品 %s", p));
return Stream.of();
}
})
.forEachOrdered(productModelDTOV2s::add); // 这将按顺序、非并行方式处理
英文:
It seems like this part of the code can be unordered and be run in parallel:
ProductModelDTOV2 ProductModelDTOV2 = dtoFactoryV2.populate(p, summary);
But this part must be ordered:
productModelDTOV2s.add(ProductModelDTOV2);
What you can do is to separate those two things. Do the first part in a flatMap
, and the second part in forEachOrdered
:
products.parallelStream().flatMap(o -> { // this block will be done in parallel
try {
return Stream.of(dtoFactoryV2.populate(p, summary));
} catch (GenericException e) {
// don't expect this message to be printed in order
log.debug(String.format("Unable to populate Product %s", p));
return Stream.of();
}
})
.forEachOrdered(productModelDTOV2s::add); // this will be done in order, non-parallel
答案2
得分: 4
以下是翻译好的内容:
正确的做法是让流创建列表:
List<Product> products = productList.getProducts();
return products.parallelStream()
.map(p -> {
try {
return dtoFactoryV2.populate(p, summary);
} catch (GenericException e) {
log.debug("无法填充产品 " + p);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
注意:代码部分保持原文不变。
英文:
The correct way to do this, would be to have the Stream create the list:
List<Product> products = productList.getProducts();
return products.parallelStream()
.map(p -> {
try {
return dtoFactoryV2.populate(p, summary);
} catch (GenericException e) {
log.debug("Unable to populate Product " + p);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论