📜 ⬆️ ⬇️

How to start working with lambda expressions in java

Hi, Habr! I present to your attention a translation of the article " How to start working with Lambda Expressions in Java " by Luis Santiago.

Before lambda expressions were added to JDK 8, I used them in languages ​​like C # and C ++. When they were added to Java, I began to study them in more detail.

With the addition of Lambda expressions, syntax elements have been added that increase the “expressive power” of Java. In this article, I want to focus on the underlying concepts that you need to become familiar with in order to start using Lambda expressions.
')

Brief introduction


Lambda expressions take advantage of parallel processes in multi-core environments, as can be seen when supporting operations with data pipelines in the Stream API.

These are anonymous methods (unnamed methods) used to implement the method defined by the functional interface. It is important to know what a functional interface is before you begin using Lambda expressions.

Functional interface


A functional interface is an interface containing one and only one abstract method.

If you look at the definition of the standard Runnable interface, you will notice how it falls into the definition of the functional interface, since it defines only one method: run ().

In the code example below, the computeName method is the abstract and only method in the MyName interface, which makes it a functional interface.

 interface MyName{ String computeName(String str); } 

Arrow operator


Lambda expressions introduce a new arrow -> operator in Java. He divides the lambda expression into 2 parts:

 (n) -> n*n 

In the left part, the parameters required for the expression are specified. This part can be empty if no parameters are required.

The right side is the body of the expression that defines its actions.
Now, using functional expressions and the operator of the arrow, you can simply create a lambda expression:

 interface NumericTest { boolean computeTest(int n); } public static void main(String args[]) { NumericTest isEven = (n) -> (n % 2) == 0; NumericTest isNegative = (n) -> (n < 0); // Output: false System.out.println(isEven.computeTest(5)); // Output: true System.out.println(isNegative.computeTest(-5)); } 

 interface MyGreeting { String processName(String str); } public static void main(String args[]) { MyGreeting morningGreeting = (str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (str) -> "Good Evening " + str + "!"; // Output: Good Morning Luis! System.out.println(morningGreeting.processName("Luis")); // Output: Good Evening Jessica! System.out.println(eveningGreeting.processName("Jessica")); } 

The variables morningGreeting and eveningGreeting in lines 6 and 7, respectively, in the example above, create a link to the MyGreeting interface and define 2 greeting expressions.

When writing a lambda expression, you can explicitly specify the type of the parameter, as is done in the example below:

 MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!"; 

Block lambda expressions


So far I have considered single lambda expressions. There is another type of expression when to the right of the arrow operator there is more than one simple expression and the so-called lambda block :

 interface MyString { String myStringFunction(String str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverseStr = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr.myStringFunction("Lambda Demo")); } 

Functional interfaces generic


Lambda expressions cannot be generic, but the functional interface associated with an expression may. You can write one common interface and return different data types, for example:

 interface MyGeneric<T> { T compute(T t); } public static void main(String args[]){ // String version of MyGenericInteface MyGeneric<String> reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Integer version of MyGeneric MyGeneric<Integer> factorial = (Integer n) -> { int result = 1; for(int i=1; i <= n; i++) result = i * result; return result; }; // Output: omeD adbmaL System.out.println(reverse.compute("Lambda Demo")); // Output: 120 System.out.println(factorial.compute(5)); } 

Using Lambda Expressions as Arguments


One common use of lambda is to pass them as arguments.
You can pass executable code to method arguments as parameters. To do this, simply make sure that the type of functional interface is compatible with the desired parameter.

 interface MyString { String myStringFunction(String str); } public static String reverseStr(MyString reverse, String str){ return reverse.myStringFunction(str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr(reverse, "Lambda Demo")); } 

These concepts will give you a good basis for getting started with lambda expressions. Take a look at your code and see where you can use them.

Source: https://habr.com/ru/post/352712/


All Articles