Is there an interface similar to Callable but with arguments?

JavaInterface

Java 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 that do not throw Exception, and in my implementation wrap exceptions in unchecked exceptions.

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;
        }
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionraisercostinView Question on Stackoverflow
Solution 1 - JavaJoachim SauerView Answer on Stackoverflow
Solution 2 - JavaShimon DoodkinView Answer on Stackoverflow
Solution 3 - JavaJosef.BView Answer on Stackoverflow
Solution 4 - JavaShadowView Answer on Stackoverflow
Solution 5 - JavaFilipe FedaltoView Answer on Stackoverflow
Solution 6 - JavaPeter LawreyView Answer on Stackoverflow
Solution 7 - JavashemerkView Answer on Stackoverflow
Solution 8 - JavaNoleshView Answer on Stackoverflow