Reputation: 289
I have the following code:
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()));
}
}
}
I tried many times but can't get the same result with Java 8 Streams.
Is it possible to get this exact behaviour with Streams? If yes, please, give me an example.
Thanks
Upvotes: 1
Views: 196
Reputation: 50716
As @Andreas said, your nested loop approach is not very efficient, but here's how you can convert it to streams:
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());
Upvotes: 1
Reputation: 159086
A cartesian join of two lists, to find objects with matching product id, is very bad for performance.
Suggest you build a Map<Integer, Product>
, of course assuming there can be only one product with a given 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());
The code is not any prettier than the original code, and now that it has been optimized to use a Map
for faster product lookup, you likely won't need parallel processing, so you might as well stick with the original code.
Or rather, fix the original code to use Map
too:
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()));
}
}
Upvotes: 3