Java. Passing a lambda expression to a method as a parameter. Examples

Passing a lambda expression to a method as a parameter. Examples


Contents


Search other websites:




1. Passing lambda expressions as method arguments. Features of use. Ways to pass a lambda expression to a method

A lambda expression can be passed to a method as an argument. The declaration of such a method must contain a reference to the corresponding functional interface. This reference is obtained as a parameter of the method that processes the lambda expression.

There are two ways to pass a lambda expression to a method:

  • passing the lambda expression directly. This method works well for lambda expressions with few operators;
  • passing a reference to the functional interface that is associated with the lambda expression. In this case, a reference to the interface is pre-declared. The lambda expression code is then assigned to this reference. This technique is appropriate when the lambda expression becomes too long to be embedded in a method call.

  

2. An example showing how to pass a lambda expression to a method

Suppose you want to pass a lambda expression to the method, which calculates the average of three numbers. To do this, the following sequence of steps is performed.

Way 1. First, the functional interface IAverage is declared, containing a method that receives three parameters and returns a result of type double

// An interface that declares a method for calculating
// the average of 3 numbers.
interface IAverage {
  double Avg(double a, double b, double c);
}

The next step is to declare a method that will receive a reference to the IAverage interface as a parameter. This method can be placed in some class as shown below

// The class containing the implementation of the method that
// receives as a parameter a reference to the IAverage interface
class SomeClass {

  // A method that displays the average of three numbers.
  // The method receives a reference to the IAverage functional interface.
  // The program code for calculating average is formed in a lambda expression,
  // which is passed as an argument to this method.
  public void PrintAverage(IAverage ref) {
    System.out.println("ref = " + ref.Avg(3, 7, 8));
  }
}

After that, in some client method (for example, the main() method), you need to pass the corresponding lambda expression to the PrintAverage() method like this:

...

public static void main(String[] args) {
  // Client code - demonstrates passing a lambda expression to a method
  // 1. Create an instance of the SomeClass class
  SomeClass obj = new SomeClass();

  // 2. Call the PrintAverage() method and pass a lambda expression to it
  obj.PrintAverage((a,b,c) -> (a+b+c)/3.0);
}

...

Way 2. With this method, a reference to the interface is pre-formed. A lambda expression is then assigned to this reference. This reference is then passed to the PrintAverage() method. This approach is useful when the code for the lambda expression is too large and makes the method invocation difficult to read. The following is a modified code from the previous example.

...

public static void main(String[] args) {
  // Client code - demonstrates passing a lambda expression to a method
  // 1. Declare a reference to the IAverage interface
  IAverage ref;

  // 2. Assign a lambda expression that calculates average
  //   of 3 values to the IAverage interface reference
  ref = (a, b, c) -> (a+b+c)/3.0;

  // 3. Create the instance of SomeClass class
  SomeClass obj = new SomeClass();

  // 4. Invoke method PrintAverage()
  obj.PrintAverage(ref);
}

  

3. Examples of solving problems in which a lambda expression is passed as an argument to a method
3.1. The maximum value in the array of numbers. Template functional interface. Passing a lambda expression to a static method

Task. Develop a lambda expression that calculates the maximum value in an array of numbers that have some numeric type T. Implement passing a lambda expression to a static method. In the method, print the maximum value to the screen.

Solution. The task declares a generic (template) functional interface IArray. The interface defines one method that receives an array of numbers of type T and returns a value of type T.

The Lambda class is the main class in the program that contains the main() function. In the main() function, the following are formed:

  • lambda expression that evaluates the maximum value in array A, which is an input parameter. Note that array A is specified by the parameter of the lambda expression without brackets [ ];
  • an array of integers that is passed to the static Solution() method.

For demonstration purposes, the Lambda class implements a static templated Solution() method that takes two parameters:

  • an array of generic type T, in which to find the maximum element;
  • a lambda expression that is passed to the method as a ref reference to the IArray functional interface.

The text of the solution to the problem is as follows

// Functional interface IArray
interface IArray<T extends Number> {
  // Method for finding the maximum in an array of numbers
  T Max(T[] array);
}

// A class containing methods that implement the lambda expression
// and test the program's operation.
public class Lambda {

  // A static template method that takes a lambda expression as a parameter.
  // The method operates on type T.
  // The T type is limited to the Number type, which means
  // that the T type can only be a numeric type (double, float, int, ...).
  // Method parameters:
  // - array of numbers of type T;
  // - a reference to the IArray<T> interface that implements the lambda expression.
  public static <T extends Number> void Solution(T[] array, IArray<T> ref) {
    // Print the maximum value in the array
    T max = ref.Max(array);
    System.out.println("max = " + max);
  }

  public static void main(String[] args) {

    // Generate a lambda expression that computes the maximum value
    // in the array of integers
    IArray<Integer> refInt = (A) -> {
      Integer max = A[0];
      for (int i=0; i<A.length; i++)
        if (max<A[i]) max = A[i];
          return max;
    };

    // Create an array of integers
    Integer[] A = { 7, 3, 2, 8, 8, 4 };

    // Pass lambda expression to Solution() method
    Lambda.Solution(A, refInt); // max = 8
  }
}

The result of the program

max = 8

  

3.2. Sorting an array of strings using the insert method. The sorting algorithm is passed by the lambda expression

The example demonstrates the use of a lambda expression to sort an array of strings by inserting.

// A functional interface for sorting an array of strings
interface ISortStrings {
  void Sort(String[] array);
}

// The class that contains the method to which the lambda expression is passed
class SortMethods {
  // A method that sorts and displays sorted strings.
  // The lambda expression is passed to the method as a ref.
  void SortStrings(String[] AS, ISortStrings ref) {
    // Sort AS array
    ref.Sort(AS);

    // Print AS array
    for (String s : AS)
      System.out.println(s);
  }
}

public class Lambda2 {

  public static void main(String[] args) {
    // 1. Declare a reference to ISortStrings
    ISortStrings ref;

    // 2. Define a lambda expression for the insertion sort algorithm.
    //    Sorting occurs in ascending order: A...Z
    ref = (s) -> {
    String tmp;
    for (int i=0; i<s.length-1; i++)
      for (int j=i; j>=0; j--)
        if (s[j].compareTo(s[j+1])>0) {
          tmp = s[j];
          s[j] = s[j+1];
          s[j+1] = tmp;
        }
    };

    // 3. Form a testing array of strings
    String[] AS = {
     "afd", "jkl", "jprst", "mno", "axf", "aaa", "bcd", "ghi"
  };

  // 4. Call the sort method SortMethods() and pass it to a lambda expression
  SortMethods obj = new SortMethods();
  obj.SortStrings(AS, ref);
  }
}

The result of the program

aaa
afd
axf
bcd
ghi
jkl
jprst
mno

  

3.3. Calculating the number of occurrences of an element in an array. Generalized functional interface

Implement a lambda expression that determines the number of occurrences of element in the array. A lambda expression implements a generic functional interface. Implement a class method that takes a lambda expression as a parameter and outputs the number of occurrences of an element in an array. Demonstrate how the method works in the main() function.

// Generalized functional interface.
interface IFindItem<T> {
  // Method for determining the number of occurrences of an element in an array
  int NOccurences(T item, T[] array);
}

// The class that contains the method to which the lambda expression is passed
class FindItems<T> {
  // The method that receives:
  // - item - the required element of type T;
  // - array - an array of elements of type T;
  // - ref - a reference to lambda-expression.
  int Find(T item, T[] array, IFindItem<T> ref) {
    // Determine the number of occurrences of item in array
    int count = ref.NOccurences(item, array);
    return count;
  }
}

// A class that contains methods that implement a lambda expression
// and test the operation of the program.
public class Lambda {

  public static void main(String[] args) {
    // Demonstrate search for strings
    // 1. Declare a reference to NOccurences
    IFindItem<String> ref;

    // 2. Form the lambda-expression for type String
    ref = (item, array) -> {
      int n = 0; // number of occurences
      for (int i=0; i<array.length; i++)
        if (item==array[i])
          n++;
      return n;
    };

    // 3. Declare array under test
    String[] AS = { "abc", "def", "abc", "ghi", "fjk", "def", "def" };

    // 4. Call the Find() method and print the number of occurrences of "def" in AS
    FindItems<String> obj = new FindItems<String>();
    int count = obj.Find("def", AS, ref); // count = 3
    System.out.println("count = " + count);
  }
}

The result of the program

count = 3

  


Related topics