0

While filtering through a list of user defined class type using Stream API has been encountered some cases where no element has been found in the list for given condition.

How to prevent exception in such case and handle according to business logic using optional class?

Stream API method looks like :

public static Optional<Policy> getPolicy(ReturnTermPolicy policyType, 
                                         String policyKey) {
    
    Optional<Policy> policy = Optional.of(policyType.getPolicies().stream()
        .filter(temp -> temp.getPolicyKey().equals(policyKey))
        .findFirst().get());
    
    return policy;
}

The calling code looks like that:

Optional<Policy> updatedPolicyOptional = getPolicy(updatedPolies,policykey); // <- exception is being generated here

if (updatedPolicyOptional.isPresent()) {
    // business logic
}
else {
    // business logic
}

Output :

Verify audit report for update made in TC_08
java.util.NoSuchElementException: No value present
    at java.util.Optional.get(Optional.java:135)
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
Arpit Aggarwal
  • 87
  • 6
  • 18

2 Answers2

3

There's no need to extract the result from the optional object just in order to wrap it with an optional again.

It's pointless and will trigger NoSuchElementException if result is not present. To solve the problem, remove the call of get() which both unsafe and redundant in this case:

public static Optional<Policy> getPolicy(ReturnTermPolicy policyType, 
                                         String policyKey) {
    
    return policyType.getPolicies().stream()
        .filter(temp -> temp.getPolicyKey().equals(policyKey))
        .findFirst();
}

In order implement your conditional logic fluently you can make use of Optional.ifPresentOrElse() which expects a Consumer that would be executed if result is present and a Runnable that will be fired in case if optional is empty. Note, this method is accessible with Java 9.

getPolicy(updatedPolies,policykey).ifPresentOrElse(policy -> doSomething(policy), 
            () -> doSomethingElse());

With Java 8 you can use Optional.ifPresentOrElse() that expects consumer and can cave the if part of conditional logic. And for the case of empty optional, you will need a condition.

Optional<Policy> policy = getPolicy(updatedPolies,policykey);
    
policy.ifPresentOrElse(policy -> doSomething(policy));
        
if (!policy.isPresent()) doSomethingElse();
Progman
  • 16,827
  • 6
  • 33
  • 48
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
1

findFirst() already returns an Optional, trying to get() it leads to an error when it is empty. So your function should be:

public static Optional<Policy> getPolicy(ReturnTermPolicy policyType, 
                                         String policyKey) {    
    return = policyType.getPolicies().stream()
        .filter(temp -> temp.getPolicyKey().equals(policyKey))
        .findFirst();        
}

And depending on your Java version (and your business logic) you can use things like:

Java 8.

if (updatedPolicyOptional.isPresent()) {
    // business logic
}
else {
    // business logic
}

or

T value = updatedPolicyOptional(mapToTFunctor).orElse(someTValue);

Java 9.

updatedPolicyOptional.ifPresentOrElse(someConsumer,someNoParamFunctor);
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69