Throw an exception if a Stream has no result

24,398

findFirst() returns an Optional so if you want to have your code throw an exception in case you didn't find anything, you should use orElseThrow to throw it.

listOfProducts
.stream()
.filter(product -> product.getProductId().equalsIgnoreCase(productId))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No products found with the  product id: "+ productId));
Share:
24,398

Related videos on Youtube

Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I need to throw an exception inside lambda and I'm not sure how to do it.

    Here is my code so far:

    listOfProducts
    .stream()
    .filter(product -> product.getProductId().equalsIgnoreCase(productId))
    .filter(product -> product == null) //like if(product==null) throw exception
    .findFirst()
    .get()
    

    I have no idea how to do that. Is there any way to do this or I just bypass it by applying filter so that filter will not forward null value like filter(product->product!=null) (even a hint will be useful :))

    Edit The actuall question is I need a product and if it is null then it will throw exception otherwise it will pass, it's not mentioned in Java 8 Lambda function that throws exception?

    The code I am trying to refactor is

    for(Product product : listOfProducts) {
      if(product!=null && product.getProductId()!=null &&
          product.getProductId().equals(productId)){
        productById = product;
        break;
      }
    }
    if(productById == null){
      throw new IllegalArgumentException("No products found with the
        product id: "+ productId);
    }
    

    I have another possible solution as

    public Product getProductById(String productId) {
            Product productById = listOfProducts.stream()
                    .filter(product -> product.getProductId().equalsIgnoreCase(productId)).findFirst().get();
    
            if (productById == null)
                throw new IllegalArgumentException("product with id " + productId + " not found!");
    
            return productById;
        }
    

    But I want to solve it using functional interface and it will be good if I can achieve this using one line in this method like

    ...getProductById()
    return stream...get();
    

    and If I need to declare a custom method to declare exception, it won't be an issue

    • RealSkeptic
      RealSkeptic over 7 years
      Well, do you need the actual exception, meaning you want to be alerted when there is a product with a null product, or do you want to ignore products with that value?
    • ACV
      ACV over 7 years
    • Admin
      Admin over 7 years
      actually filter(product->product!=null) will not allow null value to pass, and therefore can result in crash, and therefore yes I want to be notified
    • greg-449
      greg-449 over 7 years
      If possible you should use ifPresent rather than get on the Optional or you could use orElseThrow
  • Holger
    Holger over 7 years
    @HelloWorld: Just a side note, your original code skips null elements and will only fail, if there is no matching (non-null) element, whereas this code will immediately fail if it encounters a null value before the match. You have to make up your mind whether nulls ought to be allowed in the listOfProducts or not.
  • Didier L
    Didier L over 7 years
    @Holger Indeed, I removed the null check filter as the comment indicated that it was intended to throw an exception. However the non-stream code also had this null check, but then the stream version should have it before the product id filter, otherwise the latter will throw an NPE.
  • Admin
    Admin over 7 years
    I added this in final return listOfProducts.stream() .filter(product -> product.getProductId().equalsIgnoreCase(productId)) .filter(product -> product != null).findFirst() .orElseThrow(() -> new IllegalArgumentException("product not found " + productId)); hope it will block null value
  • Admin
    Admin over 7 years
    @Holger, it will check for null and I don't think I need to throw exception here :)
  • Holger
    Holger over 7 years
    @HelloWorld: you have to apply the null filter before the other as otherwise, the attempt to invoke product.getProductId() will already cause a NullPointerException if the stream encounters null.
  • Vijender Kumar
    Vijender Kumar over 6 years
    Didier L my question : if listOfProducts is empty then i want to throw an exception, saying that list of products is empty how can we do that.
  • Didier L
    Didier L over 6 years
    @VijenderKumar well just test if the list is empty and then throw your exception… If your need is more complex like that I suggest search for other similar question and then ask your own if necessary with the details of what you have tried.