如何使用java 8 Streams来处理某些条件

时间:2017-12-29 06:54:14

标签: java java-stream

我有以下代码:

List<SoldProduct> soldProducts = new ArrayList<>();
    for (Product product : products) {
        for (ProductCartDTO productCartDTO : dto.getProducts()) {
            if(product.getId().equals(productCartDTO.getIdProduct())){
               soldProducts.add(new SoldProduct(product, productCartDTO.getSerialList()));
            }
        }
    }

我尝试了很多次但是用Java 8 Streams得不到相同的结果。

使用Streams可以获得这种确切的行为吗?如果是的话,请举个例子。

由于

2 个答案:

答案 0 :(得分:3)

两个列表的笛卡尔联接,用于查找具有匹配产品ID的对象,对性能非常不利。

建议您构建Map<Integer, Product>,当然假设只有一个产品具有给定ID。

Map<Integer, Product> productById =
        products.stream()
                .collect(Collectors.toMap(Product::getId, Function.identity()));

List<SoldProduct> soldProducts =
        dto.getProducts()
           .stream()
           .filter(d -> productById.containsKey(d.getIdProduct()))
           .map(d -> new SoldProduct(productById.get(d.getIdProduct()), d.getSerialList()))
           .collect(Collectors.toList());

代码并不比原始代码更漂亮,现在它已经过优化,可以使用Map来加快产品查找速度,您可能不会需要并行处理,所以你也可以坚持使用原始代码。

或者更确切地说,修复原始代码以使用Map

Map<Integer, Product> productById = new HashMap<>();
for (Product product : products)
    productById.put(product.getId(), product);

List<SoldProduct> soldProducts = new ArrayList<>();
for (ProductCartDTO productCartDTO : dto.getProducts()) {
    Product product = productById.get(productCartDTO.getIdProduct());
    if (product != null) {
        soldProducts.add(new SoldProduct(product, productCartDTO.getSerialList()));
    }
}

答案 1 :(得分:1)

正如@Andreas所说,你的嵌套循环方法效率不高,但是你可以将它转换成流:

List<SoldProduct> soldProducts = products.stream()
    .flatMap(product -> dto.getProducts()
        .stream()
        .filter(productCartDTO -> product.getId().equals(productCartDTO.getIdProduct()))
        .map(ProductCartDTO::getSerialList)
        .map(serialList -> new SoldProduct(product, serialList)))
    .collect(Collectors.toList());