Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic functional interface

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.

like image 526
Kaskader Avatar asked Jul 18 '14 07:07

Kaskader


People also ask

What are the 4 types of functional interfaces?

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.

Can we have a generic functional interface?

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.

What is the use of generic interface in Java?

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.


2 Answers

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);
like image 130
NoDataFound Avatar answered Sep 17 '22 22:09

NoDataFound


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))'.

like image 43
Eran Avatar answered Sep 21 '22 22:09

Eran