2

I want to write a higher order function in Java which takes a lambda and returns the labmda's return value or does not return anything if the lambda has no return type.

In Kotlin, I would do something like this:

fun <T> test(block: () -> T): T {
    val r = block()
    // ...
    return r
}

Since Unit will be T in case nothing is returned, this will work.

In Java I could only come up with this:

public class Main {

    private static <T> T test(Supplier<T> s) {
        T t = s.get();
        // ...
        return t;
    }

    private static void test(Runnable r) {
        // ...
        r.run();
    }

    public static void main(String args[]) {
        test(() -> System.out.println("Hello")); // returns void
        test(() -> 5); // return an Int
    }
}

I had to overload test giving it a Supplier<T> when I want to return the lambda's return value and a Runnable if the lambda does not return anything.

Is there a better way without overloading?

Since void (but Void could) cannot take the place of T, I don't see how.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121

2 Answers2

2

Is there a better way without overloading?

No.

The best you can do is to avoid duplication in the overloads, by calling the Supplier overload from the Runnable overload:

private static void test(Runnable r) {
  test(() -> { r.run(); return null; });
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

You can accept a Supplier and provide another method to wrap Runnable:

Supplier<?> wrap(Runnable r) {
    return () -> {
        r.run();
        return null;
    };
}
shmosel
  • 49,289
  • 6
  • 73
  • 138