Reputation: 61
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
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
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