1

I was looking around for a while but could not seem to find the right answer. I am trying to reduce my code since I have a project and want to use lambda expressions. I am new to lambda and still practicing it, I came across "EXCEPTION HANDLING" with lambda in general, however, for my specific problem I could not seem to find.

I have a whole project to fix but here is an example of a code I want to reduce.

Code:

for (Customer allCustomers : cust.getAllCustomers()) {
    if (customer.getEmail().equals(allCustomers.getEmail()))
        throw new CustomerAlreadyExists(
                "ERROR: Cannot add customer. email is already in use.");

}

What I have tried:

cust.getAllCustomers()
    .stream()
    .filter(x -> x.getEmail().equals(customer.getEmail())
    .forEach(throw new CustomerAlreadyExists(
            "ERROR: Cannot add customer. email is already in use."));

My problem seems to be with throwing the exception. (Will not compile) otherwise I think the expression is fine. is there a way to throw an exception with a one liner?

thanks. Still learning.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
Shai Ace
  • 120
  • 2
  • 9
  • `Iterable.forEach` takes a `Consumer`, whose `accept` method does not have any declared checked exception. Your code would work if `CustomerAlreadyExists` is a runtime exception. If you need to throw a checked exception, read through [How can I throw CHECKED exceptions from inside Java 8 streams?](https://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams) – ernest_k Mar 13 '21 at 19:27
  • "*My problem seems to be with throwing the exception.*" - What does that mean? Does it not compile? Does it not behave as expected? I would take a different approach: stream, filter, find first, map to exception (don't throw it), check presence and if present throw. This, however, will not be a one-liner. – Turing85 Mar 13 '21 at 19:27

3 Answers3

1

You can do it like that:

cust.getAllCustomers().stream()
    .filter(x -> x.getEmail().equals(customer.getEmail())
    .forEach(s -> {throw new CustomerAlreadyExists("ERROR: Cannot add customer. email is already in use.");});
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
Dmitrii B
  • 2,672
  • 3
  • 5
  • 14
  • Thanks. that seems to solve the problem, however I was hoping for a one liner, since its not possible I will just use this. – Shai Ace Mar 13 '21 at 19:59
1

I would approach the problem differently and more in line with the throwing of an exception.

  1. Negate your filter condition
  2. Use findAny() and orElseThrow()

cust.getAllCustomers()
    .stream()
    .map(Customer::getEmail)
    .filter(Predicate.not(customer.getEmail()::equals))
    .findAny()
    .orElseThrow(() -> throw new CustomerAlreadyExists(
            "ERROR: Cannot add customer. email is already in use."));
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
0

It's a late answer but perhaps it's worth to use Stream::anyMatch to check the condition:

String email = customer.getEmail();
if (cust.getAllCustomers()
    .stream()
    .map(Customer::getEmail)
    .anyMatch(email::equals)) {
    throw new CustomerAlreadyExists("ERROR: Cannot add customer. email is already in use.")
}
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42