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

huangapple go评论68阅读模式
英文:

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&lt;Product&gt; products = productList.getProducts();
	
    List&lt;ProductModelDTOV2&gt; productModelDTOV2s = new ArrayList&lt;&gt;();
	
	products.parallelStream().forEach(p -&gt; {
		try {
			ProductModelDTOV2 ProductModelDTOV2 = dtoFactoryV2.populate(p, summary);
			productModelDTOV2s.add(ProductModelDTOV2);
		} catch (GenericException e) {
			log.debug(String.format(&quot;Unable to populate Product %s&quot;, 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 -&gt; { // this block will be done in parallel
    try {
        return Stream.of(dtoFactoryV2.populate(p, summary));
    } catch (GenericException e) {
        // don&#39;t expect this message to be printed in order
        log.debug(String.format(&quot;Unable to populate Product %s&quot;, 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&lt;Product&gt; products = productList.getProducts();

return products.parallelStream()
		.map(p -&gt; {
			try {
				return dtoFactoryV2.populate(p, summary);
			} catch (GenericException e) {
				log.debug(&quot;Unable to populate Product &quot; + p);
				return null;
			}
		})
		.filter(Objects::nonNull)
		.collect(Collectors.toList());

huangapple
  • 本文由 发表于 2020年10月25日 15:59:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/64521577.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定