I'm facing with some lambda problem.
I'm trying to use lambda expression and functional interface to create method accepting functional interface and some arguments and execute that function.
Here is my code:
@FunctionalInterface
interface TwoArgumentFunction {
public <T, K, V> T doJob(K arg1, V arg2);
} //I know I've ommited return value in that case
class SomeClass {
<T, K, V> T runLongAction(TwoArgumentFunction action, K arg1, V arg2){
SwingWorker<T, Void> worker = new SwingWorker<T, Void>(){
@Override
protected T doInBackground() throws Exception {
{... some code ... }
return action.doJob(arg1, arg2);
}
@Override
protected void done(){
{... some code ... }
}
};
worker.execute();
try {
return worker.get();
} catch (InterruptedException | ExecutionException e) {
{... some code ... }
}
}
void mainInvoke(ArgType1 arg1, ArgType2 arg2){
runLongAction((arg1, arg2) -> doSomething(arg1, arg2), arg1, arg2);
}
}
I've got error:
The method runLongAction(( arg1, arg2) -> {}, ArgType1, ArgType2) is undefined for the type SomeClass
I even tried cast lambda to TwoArgumentFunction but then I've got:
Illegal lambda expression: Method doJob of type TwoArgumentFunction is generic
Anonymouse class instead of lambda expression works fine and that's the simplest workaround I found.
It also explains Primitive Function Specializations and Pre-defined Functional interfaces like Runnable, Comparable, ActionListener, and Callable. We will also discuss four types of functional interfaces i.e. Consumer, Predicate, Function (UnaryOPerator and BinaryOperator), and Supplier.
You can create a generic functional interface. The Comparator interface with one type parameter T is an example of generic functional interface. A functional interface can have a generic abstract method. The abstract method may declare type parameters.
Generics make a class, interface and, method, consider all (reference) types that are given dynamically as parameters. This ensures type safety. Generic class parameters are specified in angle brackets “<>” after the class name as of the instance variable.
Try that :
@FunctionalInterface
interface TwoArgumentFunction<T, K, V> {
T doJob(K arg1, V arg2);
} //I know I've ommited return value in that case
public <T, K, V> T runLongAction(final TwoArgumentFunction<? extends T, ? super K, ? super V> action, final K arg1, final V arg2) {
return action.doJob(arg1, arg2);
}
private void test() {
final String a = "A";
final Long b = 1L;
this.runLongAction((ta, tb) -> {return 1;}, a, b);
}
You were putting the generics on the method, while I putted it on the interface. And I also added ? super
and ? extends
(but this work without it).
In case you don't know it and if you need it, you can also put the type in the lambda :
this.runLongAction((String ta, Long tb) -> {return 1;}, a, b);
There is no need for you to create an interface that already exists in Java 8. You should use the 'BiFunction' interface, which has a method 'R apply(T t, U u))'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With