Alexandra Dediu
Alexandra Dediu

Reputation: 61

Functional interfaces as method parameters

After wrting my own generical functional interface and used it with lambdas, I have to use it in a new method that:

Never using Functional Interfaces before, can someone please explain me how am I supposed to pass 2 functional interfaces as method parameters?

e.g of call:

applyTransformations(new Integer[]{1,2,3,4}, add, printer);
@FunctionalInterface
public interface MyFunctionalInterface<T> {
    public T doOperation(T param1, T param2, T param3, T param4);
}
public class Lambdas {
    MyFunctionalInterface<Integer> add = (i1, i2, i3, i4) -> i1 + i2 + i3 + i4;
    MyFunctionalInterface<Integer> multiply = (i1, i2, i3, i4) -> i1 * i2 * i3 * i4;
    MyFunctionalInterface<String> concatenate = (s1, s2, s3, s4) -> s1 + s2 + s3 + s4;
    MyFunctionalInterface<String> concatenateWithSpacesBetween = (s1, s2, s3, s4) -> s1 + " " + s2 + " " + s3 + " " + s4;
}

Upvotes: 1

Views: 905

Answers (2)

Naman
Naman

Reputation: 31858

In the simplest of the form, you could represent the function transformation straight forward as :

static class Lambdas {
    static MyFunctionalInterface<Integer> add = (i1, i2, i3, i4) -> i1 + i2 + i3 + i4;
    static MyFunctionalInterface<Integer> multiply = (i1, i2, i3, i4) -> i1 * i2 * i3 * i4;
    static MyFunctionalInterface<String> concatenate = (s1, s2, s3, s4) -> s1 + s2 + s3 + s4;
    static MyFunctionalInterface<String> concatenateWithSpacesBetween = (s1, s2, s3, s4) -> s1 + " " + s2 + " " + s3 + " " + s4;

    public static void main(String[] args) {
        PrintStream printer = System.out;
        applyTransformations(new Integer[]{1, 2, 3, 4}, add, printer);
        applyTransformations(new Integer[]{2, 3, 4, 5}, multiply, printer);
        applyTransformations(new String[]{"one", "day", "or", "another"}, concatenate, printer);
        applyTransformations(new String[]{"yet", "another", "way", "forward"}, concatenateWithSpacesBetween, printer);
    }

    static <T> void applyTransformations(T[] input, MyFunctionalInterface<T> functionalInterface, PrintStream printer) {
        printer.println(functionalInterface.doOperation(input[0], input[1], input[2], input[3]));
    }
}

But as you would easily notice, the solution cannot really be extended to have more than 4 elements. Not much to worry though, the developers of the JDK already took care of such simplification and provided a way to operate continuously on a stream of input taking two parameters at a time. All of this directs you towards the use of Arrays.stream and further Stream.reduce which performs the evaluation on a BinaryOperator provided. This reduces your example to

static class Lambdas {
    public static void main(String[] args) {
        PrintStream printer = System.out;
        applyTransformations(new Integer[]{1, 2, 3, 4}, Integer::sum, printer);
        applyTransformations(new Integer[]{2, 3, 4, 5}, (a, b) -> a * b, printer);
        applyTransformations(new String[]{"one", "day", "or", "another"}, String::concat, printer);
        applyTransformations(new String[]{"yet", "another", "way", "forward"}, (a, b) -> a + " " + b, printer);
    }

    static <T> void applyTransformations(T[] input, BinaryOperator<T> binaryOperator, PrintStream printer) {
        printer.println(Arrays.stream(input).reduce(binaryOperator));
    }
}

On that note, you must be careful of using the operator such as it abides by the following attributes --

an associative, non-interfering, stateless function for combining two values

Upvotes: 3

PiggyPiglet
PiggyPiglet

Reputation: 155

can someone please explain me how am I supposed to pass 2 functional interfaces as method parameters?

Answering this question specifically, you can pass functional interfaces like any other type.

private static void printAddAndConcatenate(MyFunctionalInterface<Integer> add, MyFunctionalInterface<String> concatenate) {
    System.out.println(add.doOperation(1, 1, 1, 1));
    System.out.println(concatenate.doOperation("Hel", "lo ", "Wo", "rld"));
}

public static void main(String[] args) {
    printAddAndConcatenate(Lambdas.ADD, Lambdas.CONCATENATE);
}

Upvotes: 3

Related Questions