Is there an interface in Java similar to the Callable
interface, that can accept an argument to its call method?
Like so:
public interface M
Define an interface like so:
interface MyFunction<I, O> {
O call(I input);
}
Define a method:
void getOrderData(final Function<JSONArray, Void> func){
...
JSONArray json = getJSONArray();
if(func!=null) func.call(json);
}
Usage example:
//call getOrderData somewhere in your code
getOrderData(new Function<JSONArray, Void>() {
@Override
public Void call(JSONArray input) {
parseJSON(input);
return null;
}
});
I've had the same requirement recently. As others have explained many libs do provide 'functional' methods, but these do not throw exceptions.
An example of how some projects have provided a solution is the RxJava library where they use interfaces such as ActionX where 'X' is 0 ... N, the number of arguments to the call method. They even have a varargs interface, ActionN.
My current approach is to use a simple generic interface:
public interface Invoke<T,V> {
public T call(V data) throws Exception;
// public T call(V... data) throws Exception;
}
The second method is preferable in my case but it exhibits that dreaded "Type safety: Potential heap pollution via varargs parameter data" in my IDE, and that is a whole other issue.
Another approach I am looking at is to use existing interfaces such as java.util.concurrent.Callable that do not throw Exception, and in my implementation wrap exceptions in unchecked exceptions.
Since Java 8 there is a whole set of Function-like interfaces in the java.util.function package. The one you're asking for specifically is simply Function.
Prior to Java 8, there was no general-purpose, built-in interface for this, but some libraries provided it.
For example Guava has the Function<F,T> interface with the method T apply(F input)
. It also makes heavy use of that interface in several places.
Since Java 1.8 there is a Supplier<T>
interface. It has a get()
method instead of call()
and it does not declare any Exception thrown.
The answer is ambiguous. Strictly speaking, that is, "for the same purpose of the Callable interface", there is not.
There are similar classes, and depending on what you want, they may or may not be convenient. One of them is the SwingWorker. However, as the name implies, it was designed for use within the Swing framework. It could be used for other purposes, but this would be a poor design choice.
My best advice is to use one provided by an extension library (Jakarta-Commons, Guava, and so on), depending on what libraries you already use in your system.
I just had the same issue. you can wrap any method to return a callable, and execute it's returned value. i.e.
main {
Callable<Integer> integerCallable = getIntegerCallable(400);
Future<Integer> future = executor.submit(integerCallable);
}
private Callable<Integer> getIntegerCallable(int n) {
return () -> {
try {
TimeUnit.SECONDS.sleep(n);
return 123;
} catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
};
}