Is there an interface similar to Callable but with arguments?
JavaInterfaceJava Problem Overview
Is there an interface in Java similar to the Callable
interface, that can accept an argument to its call method?
Like so:
public interface MyCallable<V> {
V call(String s) throws Exception;
}
I would rather avoid creating a new type if there already exists something that I can use. Or is there a better strategy to having multiple clients implement and plug in a callable routine?
Copied from here http://www.programmingforums.org/thread27905.html
Java Solutions
Solution 1 - Java
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.
Solution 2 - Java
at first it thought that this is done with an interface but then i found that it should be done using an abstract class.
i have solved it this way:
edit: lately i just use this:
public static abstract class callback1<T>{
public abstract void run(T value);
}
public static abstract class callback2<T,J>{
public abstract void run(T value,J value2);
}
public static abstract class callback3<T,J,Z>{
public abstract void run(T value,J value2,Z value3);
}
public static abstract class callbackret1<R,T>{
public abstract R run(T value);
}
public static abstract class callbackret2<R,T,J>{
public abstract R run(T value,J value2);
}
public static abstract class callbackret3<R,T,J,Z>{
public abstract R run(T value,J value2,Z value3);
}
CallBack.java
public abstract class CallBack<TRet,TArg> {
public abstract TRet call(TArg val);
}
define method:
class Sample2
{
CallBack<Void,String> cb;
void callcb(CallBack<Void,String> CB)
{
cb=CB; //save the callback
cb.call("yes!"); // call the callback
}
}
use method:
sample2.callcb(new CallBack<Void,String>(){
@Override
public Void call(String val) {
// TODO Auto-generated method stub
return null;
}
});
two arguments sample: CallBack2.java
public abstract class CallBack2<TRet,TArg1,TArg2> {
public abstract TRet call(TArg1 val1,TArg2 val2);
}
notice that when you use Void return type you have to use return null; so here is a variation to fix that because usually callbacks do not return any value.
void as return type: SimpleCallBack.java
public abstract class SimpleCallBack<TArg> {
public abstract void call(TArg val);
}
void as return type 2 args: SimpleCallBack2.java
public abstract class SimpleCallBack<TArg1,TArg2> {
public abstract void call(TArg1 val1,TArg2 val2);
}
interface is not useful for this.
interfaces allow multiple types match same type. by having a shared predefined set of functions.
abstract classes allow empty functions inside them to be completed later. at extending or instantiation.
Solution 3 - Java
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
Solution 4 - Java
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.
Solution 5 - Java
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.
Solution 6 - Java
Normally arguments are not required as the method can have any number of arguments in its constructor.
final int i = 5;
final String word = "hello";
Future<String> future = service.submit(new Callable<String>() {
public String call() {
return word + i;
}
});
In this example i
and word
have been used, but you can "pass" any number of parameters.
Solution 7 - Java
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);
}
};
}
Solution 8 - Java
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;
}
});