以原始顺序在数组列表中使用并行流

yal*_*ali -3 java lambda java-8

我有一个产品,我想用相同的原始顺序在另一个数组中填充产品,我使用了并行流,结果没有按原始顺序排序

    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;
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 5

It seems like this part of the code can be unordered and be run in parallel:

ProductModelDTOV2 ProductModelDTOV2 = dtoFactoryV2.populate(p, summary);
Run Code Online (Sandbox Code Playgroud)

But this part must be ordered:

productModelDTOV2s.add(ProductModelDTOV2);
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)