Learn Lambda Expressions In Java (Lambda Expressions)
When Java 8 was released, lambda phrases were a hot topic. Lambda expressions have been added to JDK version 8 to enhance Java performance by increasing the language’s expressive power.
But before entering Lambda, we must first know the user interface.
What is a user interface?
If a Java interface contains only one abstract method, it is called a functional interface. For example, the Runnable interface of the package, Java.lang, is functional because it forms only one method, run ().
Example 1: Define a user interface or interface in Java
- import java.lang.FunctionalInterface;
- @FunctionalInterface
- public interface MyInterface {
- double getValue ();
- }
Note: Annotating @ FunctionalInterface is not necessary, but it is wise to use it because the Java compiler forces the defined interface to be a functional interface and should only have an abstract method. In Java 7, the interface was called the Abstract Method Single or SAM type.
SAM was usually run with anonymous classes in Java 7.
Example 2: Run SAM with anonymous classes in Java
- public class FunctionInterfaceTest {
- public static void main (String [] args) {
- new Thread (new Runnable () {
- @Override
- public void run () {
- System.out.println (“I just implemented the Runnable Functional Interface.”);
- }
- }). start ();
- }
- }
The ability to send an anonymous class to the constructor or method made writing Java 7 code with fewer files easy. However, the structure was still tricky, and a lot of code was needed.
Java 8 went one step further, increasing the power of a SAM. Since we know that an interface has only one method, there is no need to define the name of that method when sending it as an argument. The term lambda allows us to do just that.
Familiarity with the term lambda
Lambda is essentially an unknown or unspecified method that is not executed alone. Instead, it implements the method defined by the interface.
How do you define the term lambda in Java?
The term lambda introduces a new syntactic element and operator in Java. The new operator is called the lambda operator or the arrow operator. (->)
Let’s write a simple method that returns only a constant double value.
double getPiValue () {return 3.1415; }
The lambda expression equivalent to the above method is:
() -> 3.1415
In the lambda expression, the left side specifies the required parameters of the expression, while the right is the lambda body, which determines the function of the lambda expression.
Lambda body is of two types.
1- Body with a single phrase
() -> System.out.println (“Lambdas are great”);
2- The body consists of a block of code
() -> { double pi = 3.1415; return pi; }
A lambda expression can have a parameter. For example:
(n) -> (n% 2) == 0
This lambda expression specifies that the value of n is even or odd.
If the body of the Lambda is a block of code, you should always return a value. However, a return value is not required if the lambda body is just a phrase.
Let’s write the Java code with the lambda expression that returns the value of Pi.
As mentioned earlier, the term lambda is not used alone. Executing the abstract method defined by the interface constitutes a function.
Example 3: Define the term Lambda with the user interface (interface) in Java
We must first define a MyInterface.java user interface:
- import java.lang.FunctionalInterface;
- // This is functional interface
- @FunctionalInterface
- public interface MyInterface {
- double getPiValue ();
- }
Now, let’s take the lambda expression as an example of a functional interface.
- public class LambdaMain {
- public static void main (String [] args) {
- MyInterface myInterface;
- myInterface = () -> 3.1415;
- System.out.println (“Value of Pi =” + myInterface.getPiValue ());
- }
- }
The output is equal to:
Value of Pi = 3.1415
The lambda expression must be consistent with the abstract method. That is, if you assign () -> “3.1415” to the myInterface instance, the code is defective and will not run because, by definition in the interface, the string type is not compatible with double.
You probably do not use a lambda phrase like the above in a real application. Let’s look at another example of a lambda expression that takes parameters.
Example 4: Using the term lambda with parameters in Java
- @FunctionalInterface
- MyInterface {interface
- Reverse string (String n);
- }
- public class ParamLambdaMain {
- public static void main (String [] args) {
- MyInterface myInterface = (str) ->
- String result = “”;
- for (int i = str.length () – 1; i> = 0; i–)
- result + = str.charAt (i);
- return result;
- };
- System.out.println (“Lambda reversed =” + myInterface.reverse (“Lambda”));
- }
- }
Output
Lambda reversed = adbmaL
General functional interface
The above interface only accepts String and returns the StrStringject. However, we can create a public user interface that accepts any data type.
Example 5: How can a user interface accept any data type in Java?
Let’s see how this is done:
- // GenericInterface.java
- @FunctionalInterface
- interface GenericInterface <T> {
- T func (T t);
- }
Now, Generic Interface is compatible with any Lambda expression that takes a parameter and returns a value of the same type.
- // GenericLambda.java
- public class GenericLambda {
- public static void main (String [] args) {
- GenericInterface <String> reverse = (str) -> {
- String result = “”;
- for (int i = str.length () – 1; i> = 0; i–)
- result + = str.charAt (i);
- return result;
- };
- System.out.println (“Lambda reversed =” + reverse.func (“Lambda”));
- GenericInterface <Integer> factorial = (n) -> {
- int result = 1;
- for (int i = 1; i <= n; i ++)
- result = i * result;
- return result;
- };
- System.out.println (“factorial of 5 =” + factorial.func (5));
- }
- }
Output
Lambda reversed = adbmaL
factorial of 5 = 120
Lambda Expressions and API flow
A new Java. Util. The stream package has been added to JDK8, which allows Java programmers to perform operations such as search, filter, map, reduce, or otherwise manipulate collections such as lists.
For example, we have a data stream (a string list) in which each String combines the country’s String and the country’s location. Now, we can process this data stream and retrieve only the Nepal locations.
Example 6: Demonstrate the use of Lambda with the API stream
- import java.util.ArrayList;
- import java.util.List;
- public class StreamMain {
- static List <String> places = new ArrayList <> ();
- // preparing our data
- public static List getPlaces () {
- places.add (“Nepal, Kathmandu”);
- places.add (“Nepal, Pokhara”);
- places.add (“India, Delhi”);
- places.add (“USA, New York”);
- places.add (“Africa, Nigeria”);
- return places;
- }
- public static void main (String [] args) {
- List <String> myPlaces = getPlaces ();
- System.out.println (“Places from Nepal:”);
- // Filter places from Nepal
- myPlaces.stream ()
- .filter ((p) -> p.startsWith (“Nepal”))
- .map ((p) -> p.toUpperCase ())
- .sorted ()
- .forEach ((p) -> System.out.println (p));
- }
- }
Output
Places from Nepal:
NEPAL, KATHMANDU
NEPAL, POKHARA
The API stream allows us to access methods such as filter (), map, and forEach () that can take a lambda expression as input.
We can use both built-in Java methods and define our expressions based on the technique we learned above. As we saw in the example above, this dramatically reduces the lines of code.