Search code examples
javafunctional-programmingjava-streamoption-type

No instance(s) of type variable(s) U exist so that void conforms to U


I am trying to avoid isPresent checks in my code below, but the compiler emits an error with the message

"No instance(s) of type variable(s) U exist so that void conforms to U"

on the call to printAndThrowException. This is my code:

values.stream()
    .filter(value -> getDetails(value).getName.equals("TestVal"))
    .findFirst()
    .map(value -> printAndThrowException(value))
    .orElseThrow(new Exception2("xyz"));

The method in question printAndThrowException has the below signature:

void printAndThrowException(Pojo value)

The above method always throws an exception of type RuntimeException. The abovementioned code isn't the exact code, just transformed my code to represent the situation.

What's the problem here and how to avoid using isPresent when calling printAndThrowException?


Solution

  • Optional.map() expects a Function<? super T, ? extends U> as parameter. Since your method returns void, it cannot be used like this in the lambda.

    I see three options here:

    • make that method return Void/Object/whatever instead – semantically not ideal but it would work
    • make that method return the exception, and change the lambda definition to
      .map(v -> {
          throw printAndReturnException();
      });
      
    • use ifPresent(), and move the orElseThrow() outside of the call chain:
      values.stream()
          .filter(value -> getDetails(value).getName.equals("TestVal"))
          .findFirst()
          .ifPresent(value -> printAndThrowException(value))
      throw new Exception2("xyz");