4

Here is what I tried. and it does not even compile.

public class LambdaExample {

    public static Integer handleOperation(Integer x, Integer y,  Function converter){
                return converter.apply(x,y);
    }

    public static void main(String[] args){
         handleOperation(10,10, Operation::add);
    }

}

class Operation {

    public int add(Integer x, Integer y){
        return x+y;
    }

}

Couple of things I am trying to acheive/learn here is:

1) how to pass lambda expression as method parameter ( in main method above)

2) how to pass parameters to the function (in handleOpertion method, there is compilation error that apply takes only one parameter)

brain storm
  • 30,124
  • 69
  • 225
  • 393

3 Answers3

5

A Function takes an input x and yield a result y. Thus you are not looking for a Function (not mentioning that you used a raw type) when doing return converter.apply(x,y);, but for a BiFunction<Integer, Integer, Integer> or more simpler, a BinaryOperator<Integer> since every type parameter is identical.

1) how to pass lambda expression as method parameter ( in main method above)

By providing a lambda expression that respect the contract of the BinaryOperator<Integer> interface, i.e a method that takes two Integer as parameter and return an Integer.

handleOperation(10,10, (a, b) -> a + b)

2) how to pass parameters to the function (in handleOpertion method, there is compilation error that apply takes only one parameter)

Because a function is of the form f => u thus the apply method takes a single argument and yield a single result, like a mathematical function such as f(x) = 2 * x (refer to the first part of the answer).

Here is what I tried. and it does not even compile.

To make your code compile, you can either make the method static or create a new instance before using the method reference. Then it will refer to the add method of the new instance when handleOperation will call the apply method of the function.

handleOperation(10,10, new Operation()::add);

Note that this method already exists in the JDK, it's Integer::sum. It takes two primitive int values instead of Integer references but it's close enough so that the auto-boxing mechanism will make this method valid to appear as a BinaryOperator<Integer> in the method context.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
4

Your handleOperation method takes an object that implements Function, Operation::add (a method reference) doesn't qualify. Also, for two arguments, you'll need to use BiFunction instead.

Here's an example that should work:

public class LambdaExample {

    public static Integer handleOperation(Integer x, Integer y,  BiFunction<Integer, Integer, Integer> converter){
                return converter.apply(x,y);
    }

    public static void main(String[] args){
         handleOperation( 10,10, new Operation() ); // should return 20
    }

}

class Operation implements BiFunction<Integer, Integer, Integer> {

    public Integer apply(Integer x, Integer y){
        return x+y;
    }

}

Updated:

public class LambdaExample {

    public static Integer handleOperation(Integer x, Integer y,  BiFunction<Integer, Integer, Integer> converter){
                return converter.apply(x,y);
    }

    public static void main(String[] args){
         handleOperation( 10,10, Operation::add ); // should return 20
    }

}

class Operation {

    public static int add(Integer x, Integer y){
        return x+y;
    }

}
Don Bottstein
  • 1,640
  • 13
  • 17
  • NO this is not what I wanted.. I want to pass "add" function in lambda. I dont want to pass `new Operation()` there.. – brain storm May 27 '15 at 22:55
3

Your Function parameter is raw (untyped) and should be a BiFunction.

Try this:

public static Integer handleOperation(Integer x, Integer y,  BiFunction<Integer, Integer, Integer> converter){
    return converter.apply(x,y);
}

A BiFunction with all 3 types the same can replaced with a (single-typed) BinaryOperator:

public static Integer handleOperation(Integer x, Integer y,  BinaryOperator<Integer> converter){
    return converter.apply(x,y);
}

To call it, you can do this:

int sum = handleOperation(1, 2, (x, y) -> x + y); // 3

Actually, you have implemented a reduction. This call could equally be written as:

int sum = Stream.of(1, 2).reduce((x, y) -> x + y);
Bohemian
  • 412,405
  • 93
  • 575
  • 722