我有以下代码:
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可以获得这种确切的行为吗?如果是的话,请举个例子。
由于
答案 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());