Reputation: 3091
I've heard that it's not always a good practice to handle runtime exceptions. I've implemented a method that takes a product rating as an argument and if the current product object has this rating, it returns a ProductDTO object. The only way I found to make the method work as expected is with the use of a Runtime exception. But according to Joshua Bloch it is a very bad idea to use exceptions for control flow.
Is there a way to improve the logic of the method?
public ProductDTO findByRating(int productRating) {
ProductDTO productDTO = new ProductDTO();
if (productRating == this.avgRating()) {
productDTO.setProductName(productName);
productDTO.setProductsLeftForSale(productsLeftForSale());
productDTO.setAvgRating(avgRating());
productDTO.setTotalVotes(reviews.size());
return productDTO;
} else {
throw new RuntimeException(String.format("No Product found with the rating: %s", productRating));
}
}
.
List<ProductDTO> productDTOList = new ArrayList<>();
int rating = 5;
for (BaseProduct product : products) {
try {
ProductDTO productDTO = product.findByRating(rating);
if (productDTO != null) {
productDTOList.add(productDTO);
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
Upvotes: 0
Views: 78
Reputation: 498
Maybe it looks a little better:
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
...
public Optional<ProductDTO> findByRating(int rating) {
return this.avgRating() == rating ? Optional.of(createDTO()) : Optional.empty();
}
private ProductDTO createDTO() {
ProductDTO productDTO = new ProductDTO();
productDTO.setProductName(productName);
productDTO.setProductsLeftForSale(productsLeftForSale());
productDTO.setAvgRating(avgRating());
productDTO.setTotalVotes(reviews.size());
return productDTO;
}
public List<ProductDTO> findProductsByRating(int rating) {
return products.stream()
.map(product -> product.findByRating(rating))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
Upvotes: 2