Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Runnable to Supplier

How can a Runnable be converted to a Supplier?

public <T> T useSupplier(Supplier<T> supplier) {
    // Does something with supplier and returns supplied value
    ...
    return value;
}

public void useRunnable(Runnable runnable) {
    // Somehow convert runnable to Supplier
    ...
    useSupplier(supplier);
}

Here I would like to reuse the method useSupplier for useRunnable, for example because I do not want to duplicate the code. The behavior of useSupplier does not matter for this question, let's say it wraps thrown exceptions, or uses the supplier in a synchronized block.


Edit: To clarify, the method useSupplier does not interact with the supplied value, it just returns it. The functionality of useSupplier is to retrieve the value from the supplier in some context, in my case it catches (specific) RuntimeExceptions, creates a new exception with it as cause and throws it:

public <T> T useSupplier(Supplier<T> supplier) {
    try {
        return supplier.get();
    }
    catch (RuntimeException runtimeException) {
        throw new MyException("Supplier threw exception", runtimeException);
    }
}

The following solutions do not work (in Java 8):

useSupplier(runnable);
useSupplier(runnable::run);
useSupplier((Supplier<Void>) runnable::run);

One solution I could come up with is creating a new Supplier which returns an arbitrary value:

useSupplier(() -> {
    runnable.run();
    return null;
});

Is there a smaller solution?

Edit: As pointed out by Holger in the comments, using runnable::run will also create new lambda instances since it is stateful, see also this answer.

like image 845
Marcono1234 Avatar asked Feb 10 '19 15:02

Marcono1234


People also ask

Is callable a supplier?

Callable is also designed to be run on another thread. Supplier on the other hand, is very general. It just "supplies a value" and that's it. So Callable is more specialised than Supplier .

Is functional interface runnable?

Interface RunnableThis is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.

What is supplier interface?

Interface Supplier<T>Represents a supplier of results. There is no requirement that a new or distinct result be returned each time the supplier is invoked. This is a functional interface whose functional method is get() . Since: 1.8.

Why should we use supplier Java?

Java's functional supplier interface can be used any time a function needs to generate a result without any data passed into it. Now, contrast that with Java's functional Consumer interface which does the opposite. The Consumer interface will pass data, but no result will be returned to the calling program.


1 Answers

In your case you cannot avoid creating new object. Even if there is a method somewhere that converts a Runnable to a Supplier, it will create an object there. So your solution is valid, you won't find any better.

Pay attention to that Supplier is expected to provide values and Runnable just represents an action. They are used for different purposes. So your need of converting Runnable to Supplier may be a result of a design problem involved.

like image 160
Sergey Belonozhko Avatar answered Sep 28 '22 02:09

Sergey Belonozhko