Lambda expressions for generic functional interfaces. Examples
Contents
- 1. Features of using generics (templates) in functional interfaces
- 2. Solutions to problems of building lambda expressions that implement generalized functional interfaces. Examples
- Related topics
Search other websites:
1. Features of using generics (templates) in functional interfaces
The functional interface can be generic (template). In this case, the target type of the lambda expression is determined based on the type specified in the reference to that functional interface.
For example. Let the generalized functional interface IValue be given
// Generalized (template) functional interface. // This interface operates on the generic type T. interface IValue<T> { T GetValue(); }
The IValue<T> interface operates on the generic type T. The interface declares an abstract method GetValue() that returns a value of type T. Therefore, this functional interface is compatible with any lambda expression that takes one parameter and returns a value of the same type. When declaring a reference to the IValue<T> functional interface, you must specify the target type of the lambda expression in the type argument:
// Declare a reference to the IValue functional interface, // which will operate on the Float type IValue<Float> refIValue;
After that, you can form a lambda expression and call the GetValue() method
// Set a lambda expression with reference to the type Float refIValue = () -> 3.1415f; // return the value of float type // Invoke method GetValue(), which returns 3.1415f float v = refIValue.GetValue(); // v = 3.1415
If, when forming a lambda expression, you try to return a value of another (incompatible) type
refIValue = () -> "Hello world!"; // here the type is String and not Float
then the compiler will generate an error like
Type mismatch: cannot convert from String to Float
For the lambda expression to return a String type, you must declare a new reference to the IValue interface with an argument of type String (IValue<String>).
⇑
2. Solutions to problems of building lambda expressions that implement generalized functional interfaces. Examples
2.1. Building a lambda expression that returns a numeric value
The example demonstrates:
- declaration of a generic (template) functional interface IValue<T>, operating on the T type;
- creating a lambda expression and using it for the numeric type Float. The lambda expression implements the generic IValue<T> functional interface.
// Generalized (template) functional interface. // This interface operates on the generic type T. interface IValue<T> { T GetValue(); } public class TrainLambda02 { public static void main(String[] args) { // Declare a reference to the IValue functional interface // that will operate on the Float type IValue<Float> refIValue; // Set a lambda expression with reference to the type Float refIValue = () -> 3.1415f; // return the value of float type // Invoke method GetValue(), which returns 3.1415f float v = refIValue.GetValue(); // v = 3.1415 System.out.println("v = " + v); } }
The result of the program
v = 3.1415
⇑
2.2. Lambda expression that implements elementwise summation of arrays of numbers
Task. Develop a program in which element-wise summation of arrays of 10 numbers is carried out. The type of numbers can be any numeric (int, double, float, …). Implement array summation using a lambda expressions.
Solution. To sum two arrays of numbers, you need to implement the ISumArrays functional interface, which contains one SumArrays() method. This method must receive two parameters – arrays of numbers. The method must return a result – an array of numbers, which is the sum of two parameter arrays.
The problem statement says that the type of numbers can be any numeric (int, double, float, …). This means that you need to develop a generic (template) ISumArrays interface for some type T. Since T is restricted to numeric types, it must be restricted to Number.
In the main() function, you need to test the operation of the created functional interface.
Below is the text of the program that solves this problem.
// ISumArrays templated functional interface interface ISumArrays<T extends Number> { T[] SumArrays(T[] A, T[] B); } // A class containing methods that implement the lambda expression // and test the program's operation. public class Lambda { public static void main(String[] args) { // 1. Declare ISumArrays reference for Double type ISumArrays<Double> ref; // 2. Create two arrays of double type Double[] A1 = { 2.5, 1.4, 0.9, 1.1, 2.7, 2.9, 1.3, 2.0, 5.5, 1.2 }; Double[] A2 = { 1.5, 1.0, 0.6, 1.7, 0.7, 0.2, 0.3, 0.2, 1.1, 3.3 }; // 3. Generate lambda expression for Double type ref = (A, B) -> { Double[] C = new Double[A.length]; // numeric type in arrays for (int i=0; i<A.length; i++) { // sum two numbers as double C[i] = A[i].doubleValue() + B[i].doubleValue(); } return C; }; // 4. Call the method of a functional interface Double[] A3 = (Double[])ref.SumArrays(A1, A2); // 5. Print the result System.out.print("A3: "); for (Double t : A3) System.out.print(" " + t); System.out.println(); } }
In the above code, you should pay attention to how arrays of numbers are passed to the lambda expression
... ref = (A, B) -> { Double[] C = new Double[A.length]; // numeric type in arrays for (int i=0; i<A.length; i++) { // sum two numbers as double C[i] = A[i].doubleValue() + B[i].doubleValue(); } return C; }; ...
Since the type of the lambda expression parameter is determined from the target context, arrays in the lambda expression are passed as A and B. The A parameter is associated with A[]. The B parameter is associated with B[].
⇑
2.3. Calculating the number of occurrences of a given element in an array
Task. Develop a program that demonstrates the use of a lambda expression to find an element in an array. The program should contain a generalized functional interface. Implement a lambda expression for the String type.
Solution. The text of the program that solves this problem is as follows.
// Template functional interface IFindItem interface IFindItem<T> { // a method that calculates the number of occurrences // of a given element in an array of numbers int Search(T item, T[] items); } // A class that contains methods that implement // a lambda expression and tests the operation of the program. public class Lambda { public static void main(String[] args) { // 1. Declare a functional interface reference for type String IFindItem<String> ref; // 2. Define lambda expression ref = (item, items) -> { int count=0; for (int i=0; i<items.length; i++) if (item==items[i]) count++; return count; }; // 3. Create array of strings String[] AS = { "abc", "abd", "def", "acf", "abc", "afx" }; // 4. Test lambda expression int count = ref.Search("abc", AS); System.out.println("count = " + count); // count = 2 } }
The result of the program
count = 2
⇑
Related topics
- Lambda expressions. Basic concepts. Functional interface. Examples
- Passing a lambda-expression to a method as a parameter. Examples
- Throwing exceptions in lambda expressions. Examples
- Accessing class members from a lambda expression. Capturing variables in lambda expressions. Examples
⇑