# Java. Lambda expressions. Basic concepts. Functional interface. Generalized functional interfaces and lambda expressions. Examples

### Contents

- 1. The concept of lambda expression. The advantages of using lambda expressions
- 2. Lambda expression (closure). General form. Lambda operator
**->**. Examples - 3. Functional interface. Definition. General form. Examples
- 4. Sequence of steps for building lambda expressions
- 5. Solving problems with lambda expressions
**Related topics**

**Search other Web sites:**

##### 1. The concept of lambda expression. The advantages of using lambda expressions

Lambda expressions were introduced in JDK 8 to enhance the Java language. Lambda expressions are also called closures.

The advantages of using lambda expressions in the Java language include the following:

- the use of new elements that increase the expressiveness of the Java language. The implementation of some common constructions is simplified;
- expanding the capabilities of the program interface library (API). This can include simplifying parallel processing, improving the work with I/O streams in the API.

The advent of lambda expressions has fueled new features in the Java language such as default methods and the use of method references without executing them.

### ⇑

##### 2. Lambda expression (closure). General form. Lambda operator ->. Examples

The implementation of any lambda expression is based on the use of two language constructs:

- directly lambda expressions;
- functional interface.

A lambda expression is an anonymous (unnamed) method that does not execute on its own, but implements a method declared in a functional interface (see point 3). If a lambda expression is encountered in the program, this leads to the creation of some anonymous class containing an anonymous method, the code of which is defined in the lambda expression.

When declaring a lambda expression, the lambda operator is used, which is denoted by the symbols **->** (arrow). The lambda operator is interpreted as “becomes” or “passes”. The lambda operator (**->**) splits a lambda expression into two parts: left and right. On the left side of the lambda expression, parameters are specified. On the right side, there are actions (operators) that define the code of the lambda expression.

The lambda expression code can be generated in one of two ways:

- contain a single expression. In this case, the lambda expression is said to be
*single*; - enclosed in curly braces
**{ }**. This is the case when several operators need to be specified on the right side of the lambda operator. In this case, the lambda expression is called a block expression. When returning a result in block lambda expressions, you must specify the return statement. In the simplest case, a block lambda expression declaration can be as follows:

(list_of_parameters) -> { // Lambda expression body // ...returnresult; }

here

*list_of_parameters*– a list of parameters that the lambda expression receives. The list of parameters is specified, separated by commas, just like in the method. The parameter list is indicated on the left side of the lambda operator. The parameters of the lambda expression must be compatible in type and number with the parameters of the abstract method that is declared in the functional interface.

If the lambda expression contains a single parameter, it can be without parentheses **( )**:

```
i -> {
// ...
}
```

It is possible that the lambda expression does not receive parameters. In this case, the general form of a block lambda expression is

() -> { // Lambda expression body // ... }

If the lambda expression uses one operator (expression), then the curly braces can be omitted:

(list) ->expression;

here

*list*– the list of parameters*expression*– expression to be calculated using the lambda expression.

**Example**** 1.** Below is a lambda expression without parameters that returns the number ** π**:

`() -> Math.`*PI*

In the above code, the result of the lambda expression is the PI constant from the Math class. Another solution could have been written

() -> 3.1415

**Example**** 2.** A lambda expression that takes two integer parameters and returns their multiplication.

(inta,intb) -> a*b

**Example**** 3.** A lambda expression that, given the lengths of the three sides a, b, c returns the area of a triangle.

(doublea,doubleb,doublec ) -> {if(((a+b)<c) || ((a+c)<b) || ((b+c)<a))return0.0;else{doublep = (a+b+c)/2; // semiperimeterdoubles = Math.sqrt(p*(p-a)*(p-b)*(p-c)); // Heron's formulareturns; } }

### ⇑

##### 3. Functional interface. Definition. General form. Examples

*Functional interface* is an interface that contains only one abstract method. The functional interface defines only one action (operation). The functional interface defines the target type of the lambda expression. The functional interface is also called SAM-type (Single Abstract Method).

In the most general case, a functional interface declaration looks like this:

interface InterfaceName {return_typeMethodName(list_of_parameters); }

here

*InterfaceName*– the name of the functional interface;*MethodName*– the name of the method that defines the purpose of the interface;*return_type*– the type that MethodName returns;*list_of_parameters*– a list of parameters for the MethodName method.

If two or more abstract methods are declared in an interface, then this interface is not considered a functional interface.

**Example**** 1.** A functional interface is declared that defines an abstract method that takes no parameters and returns an integer

// An interface that defines a parameterless method that returns an integerinterfaceINumber {intGetNumber(); }

The lambda expression code that implements this interface can be, for example, the following:

```
// Lambda expression that implements the INumber interface
INumber lambdaNumber = () -> 255;
```

After the lambda expression is formed, you can call the GetNumber() method of the INumber interface

// Using a lambda expression as the GetNumber() Methodintnumber = lambdaNumber.GetNumber(); // number = 255 System..println("number = " + number);out

**Example**** 2.** A functional interface is declared that defines a method, receives 3 numbers of type double and returns a value of type double

// An interface that defines an abstract method // that receives 3 double parameters and returns a double.interfaceICalculation {doubleCalcMethod(doublea,doubleb,doublec); }

For such a method signature, you can implement lambda expressions that perform various operations on three numbers, for example:

- calculate the sum of three numbers;
- calculate the maximum (minimum) value among the three numbers, etc.

Following is the construction and use of a lambda expression that calculates the sum of three numbers

// Forming the CalcMethod() method, which calculates // the sum of 3 numbers of double type using a lambda expression ICalculation ICalc = (a, b, c) -> a+b+c; // 2. Calculate the sum of integers 1 + 2 + 3intsum = (int)ICalc.CalcMethod(1, 2, 3); System..println("sum = " + sum);out

As you can see from the above code, you can use integer types in a method that operates on the double type.

### ⇑

##### 4. Sequence of steps for building lambda expressions

In order to use lambda expressions in the program, you need to perform the following steps:

- Declare a functional interface
**I**containing only one abstract method**M**. The signature of the parameters of the**M**method and the type of the returned result must correspond to the problem being solved. - Declare a Ref reference to functional interface
**I**in the method where you want to use the lambda expression. - Generate the lambda expression code according to the syntax and assign this code to the Ref to the functional interface. The number of parameters in the lambda expression must match the number of parameters that are declared in method
**M**of functional interface**I**. - Using the Ref reference, call the method
**M**. The call looks like this:

Ref.M(parameters)

here *parameters* – list of parameters of the M() method.

### ⇑

##### 5. Solving problems with lambda expressions

##### 5.1. Lambda expression that processes three numbers

Create and invoke a lambda expression that evaluates:

- the sum of three numbers;
- the maximum value of three numbers.

Implement the task using a functional interface.

packageTrainLambda; // Declare a functional interfaceinterfaceMyNumber { // A method that takes three double parameters // and returns the result of double typedoubleGetValue(doublea,doubleb,doublec); }publicclassTrainLambda01 {publicstaticvoidmain(String[] args) { // Using the functional interface MyNumber // 1. Declare a reference to functional interface MyNumber mn; // 2. Assign a lambda expression to the mn reference, // here an instance of the class with the implementation // of the GetValue () method is created. The mn reference // is a reference to this class instance. mn=(a,b,c)->a+b+c; // single lambda expression // 3. Call the GetValue() method and display the resultdoubleres = mn.GetValue(5, 7.5, 3.8); System..println("res = " + res); // -------------------------------- // 4. Calculating the maximum of three numbers // Generate a new block lambda expression mn=(a,b,c) -> {outdoublemax=a;if(max<b) max=b;if(max<c) max=c;returnmax; }; // Calling the GetValue() method and displaying the resultdoublemax = mn.GetValue(5.3, 8.3, 4.2); System..println("max = " + max); } }out

The result of the program

res = 16.3

### ⇑

##### 5.2. Lambda expression that is used in a method parameter to process an array of numbers

Implement and demonstrate a method that calculates the sum of paired and unpaired elements of an integer array. The method must receive as a parameter a lambda expression that determines the parity of the element and use it for calculations. Demonstrate the method for lambda expressions that:

- determine if the array element is paired;
- determine if the array element is unpaired.

packageTrainLambda; // A functional interface that checks a number for parity. // This interface contains only 1 method // that takes an integer and returns a boolean result.interfaceOdd { // An abstract method for checking the parity of an int numberbooleanIsOdd(intd); } // A class containing the method that calculates the sum of the elements of an arrayclassSumArray { // A method that calculates the sum of the elements of array. // The sum is calculated using the return result from the lambda expression. // The method receives 2 parameters: // - A is the array to sum; // - refLambda - reference to Odd functional interface.publicintSum(int[] A, Odd refLambda) {intsum=0;for(inti=0; i<A.length; i++)if(refLambda.IsOdd(A[i])) // is the array element paired? sum+=A[i];returnsum; } }publicclassTrainLambda01 {publicstaticvoidmain(String[] args) { // Passing a lambda expression to a method as an argument. // 1. Declare a reference to the interface Odd Odd ref1; // 2. Assign lambda expression to ref1 ref1 = (d) -> { // parity check codeif(d%2==0)returntrue;elsereturnfalse; }; // 3. Demonstrate calling the Sum() method of the SumArray class and passing it a lambda expression // 3.1. Create an instance of the SumArray class SumArray obj1 =newSumArray(); // 3.2. Declare an array of integersint[] A = { 5, 3, 8, 10, 2, 1, 2, 3 }; // 3.3. Call the method for calculating the sum of array elements // with a lambda expression that selects only paired elementsintsum = obj1.Sum(A, ref1); System..println("sum = " + sum); // 3.4. Passing a lambda expression to a method for unpaired elements sum = obj1.Sum(A, (Odd)((d) -> {outif(d%2!=0)returntrue;elsereturnfalse; })); System..println("sum = " + sum); } }out

The result of the program

sum = 22 sum = 12

In the above code, you can use a method reference by example:

instance_name::method_name

In the program, passing the IsOdd() method to the Sum() method will look like this:

// also works - a reference to the instance method is passedintsum = obj1.Sum(A, ref1::IsOdd);

### ⇑

##### 5.3. Lambda expression using pattern (generic)

Create and invoke a lambda expression using a template (generic). The lambda expression must match at most three digits.

packageTrainLambda; // Generalized (template) functional interface. // Contains a method that takes 3 numbers of type T // and returns a value of type T.interfaceMax3<T> { T Max(T a, T b, T c); }publicclassTrainLambda02 {publicstaticvoidmain(String[] args) { // Using the Max3<T> interface // 1. Declare the reference to Max3<T> interface Max3<Integer> refInt; // 2. Create a lambda expression with reference to int refInt = (a, b, c) -> { Integer max = a;if(max<b) max=b;if(max<c) max=c;returnmax; }; // 3. Invoke lambda expression for three integersintres = refInt.Max(5, 7, 3); // res = 7 System..println("res = " + res); // 4. Create lambda-expression for double type Max3<Double> refDouble; refDouble = (a, b, c) -> { Double max = a;outif(max<b) max=b;if(max<c) max=c;returnmax; }; // 5. Call the lambda expression with reference to the double typedoubleresMax = refDouble.Max(3.88, 2.55, 4.11); System..println("resMax = " + resMax); } }out

### ⇑

##### 5.4. Solving a quadratic equation using a lambda expression

The task demonstrates the use of a lambda expression to solve a quadratic equation. The program contains the following components:

- functional interface Equation. The interface declares one method that receives three double parameters. These parameters are the coefficients a, b, c of the quadratic equation. The method returns the value of the roots of the equation as an instance of the Solution class. If the equation has no solution, then the method returns null;
- Solution class – contains two fields x1, x2 of type double, which are the roots of a quadratic equation;
- the TrainLambda02 class containing the main() function. This function builds and uses a lambda expression to solve a quadratic equation for the values a = 2, b = 8, c = 4.

The program text is as follows:

// A functional interface for solving a quadratic equation.interfaceEquation { // The method receives the parameters - coefficients of equation a*x^2 + b*x + c = 0. // If the equation has no solution, then the method returns null. // Otherwise, the method returns an instance of the Solution class // with roots x1, x2. Solution CalcEquation(doublea,doubleb,doublec); } // The result of solving a quadratic equationclassSolution {doublex1;doublex2; }publicclassTrainLambda02 {publicstaticvoidmain(String[] args) { // Lambda expression that solves a quadratic equation. // The result is returned in an instance of the Solution class. // 1. Declare a reference to the functional interface Equation eq; // 2. Assign a lambda expression that solves a quadratic equation // to the reference eq = (doublea,doubleb,doublec) -> {doubled = b*b - 4*a*c; // discriminantif(d>=0) { // Find roots Solution roots =newSolution(); roots.x1 = (-b-Math.sqrt(d))/(2*a); roots.x2 = (-b+Math.sqrt(d))/(2*a);returnroots; }elsereturnnull; }; // 3. Solve the quadratic equation 2*x^2 - 8*x + 4 = 0 Solution roots = eq.CalcEquation(2, -8, 4);if(roots==null) System..println("The solution has no roots.");outelse{ System..println("x1 = " + roots.x1); System.out.println("x2 = " + roots.x2); } } }out

The result of the program

x1 = 0.5857864376269049 x2 = 3.414213562373095

### ⇑

### Related topics

- Lambda expressions for generic functional interfaces. 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

### ⇑