Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Java

Expresiones Java Lambda

Expresiones Java Lambda

En este artículo, aprenderemos sobre la expresión lambda de Java y el uso de la expresión lambda con interfaces funcionales, interfaz funcional genérica y API de transmisión con la ayuda de ejemplos.

La expresión lambda se introdujo por primera vez en Java 8. Su objetivo principal es aumentar el poder expresivo del lenguaje.

Pero, antes de entrar en lambdas, primero debemos entender las interfaces funcionales.


¿Qué es la interfaz funcional?

Si una interfaz Java contiene uno y solo un método abstracto, se denomina interfaz funcional. Este único método especifica el propósito previsto de la interfaz.

Por ejemplo, el Runnable interfaz del paquete java.lang; es una interfaz funcional porque constituye solo un método, es decir, run() .

Ejemplo 1:Definir una interfaz funcional en java

import java.lang.FunctionalInterface;
@FunctionalInterface
public interface MyInterface{
    // the single abstract method
    double getValue();
}

En el ejemplo anterior, la interfaz MyInterface solo tiene un método abstracto getValue(). Por lo tanto, es una interfaz funcional.

Aquí, hemos usado la anotación @FunctionalInterface . La anotación obliga al compilador de Java a indicar que la interfaz es una interfaz funcional. Por lo tanto, no permite tener más de un método abstracto. Sin embargo, no es obligatorio.

En Java 7, las interfaces funcionales se consideraban como métodos abstractos únicos o SAM escribe. Los SAM se implementaron comúnmente con clases anónimas en Java 7.

Ejemplo 2:Implementar SAM con clases anónimas en java

public class FunctionInterfaceTest {
    public static void main(String[] args) {

        // anonymous class
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I just implemented the Runnable Functional Interface.");
            }
        }).start();
    }
}

Salida :

I just implemented the Runnable Functional Interface.

Aquí, podemos pasar una clase anónima a un método. Esto ayuda a escribir programas con menos códigos en Java 7. Sin embargo, la sintaxis seguía siendo difícil y se requerían muchas líneas de código adicionales.

Java 8 amplió la potencia de un SAM yendo un paso más allá. Como sabemos que una interfaz funcional tiene solo un método, no debería haber necesidad de definir el nombre de ese método al pasarlo como argumento. La expresión lambda nos permite hacer exactamente eso.


Introducción a las expresiones lambda

La expresión lambda es, esencialmente, un método anónimo o sin nombre. La expresión lambda no se ejecuta por sí sola. En su lugar, se utiliza para implementar un método definido por una interfaz funcional.

¿Cómo definir la expresión lambda en Java?

Así es como podemos definir la expresión lambda en Java.

(parameter list) -> lambda body

El nuevo operador (-> ) utilizado se conoce como operador flecha u operador lambda. Es posible que la sintaxis no esté clara en este momento. Exploremos algunos ejemplos,

Supongamos que tenemos un método como este:

double getPiValue() {
    return 3.1415;
}

Podemos escribir este método usando la expresión lambda como:

() -> 3.1415

Aquí, el método no tiene ningún parámetro. Por lo tanto, el lado izquierdo del operador incluye un parámetro vacío. El lado derecho es el cuerpo lambda que especifica la acción de la expresión lambda. En este caso, devuelve el valor 3,1415.


Tipos de cuerpo Lambda

En Java, el cuerpo lambda es de dos tipos.

1. Un cuerpo con una sola expresión

() -> System.out.println("Lambdas are great");

Este tipo de cuerpo lambda se conoce como cuerpo de expresión.

2. Un cuerpo que consta de un bloque de código.

() -> {
    double pi = 3.1415;
    return pi;
};

Este tipo de cuerpo lambda se conoce como cuerpo de bloque. El cuerpo del bloque permite que el cuerpo lambda incluya varias declaraciones. Estas declaraciones están encerradas entre llaves y debe agregar un punto y coma después de las llaves.

Nota :Para el cuerpo del bloque, puede tener una declaración de devolución si el cuerpo devuelve un valor. Sin embargo, el cuerpo de la expresión no requiere una declaración de retorno.


Ejemplo 3:Expresión Lambda

Escribamos un programa Java que devuelva el valor de Pi usando la expresión lambda.

Como se mencionó anteriormente, una expresión lambda no se ejecuta por sí sola. Más bien, forma la implementación del método abstracto definido por la interfaz funcional.

Entonces, primero debemos definir una interfaz funcional.

import java.lang.FunctionalInterface;

// this is functional interface
@FunctionalInterface
interface MyInterface{

    // abstract method
    double getPiValue();
}

public class Main {

    public static void main( String[] args ) {

    // declare a reference to MyInterface
    MyInterface ref;
    
    // lambda expression
    ref = () -> 3.1415;
    
    System.out.println("Value of Pi = " + ref.getPiValue());
    } 
}

Salida :

Value of Pi = 3.1415

En el ejemplo anterior,


Expresiones Lambda con parámetros

Hasta ahora hemos creado expresiones lambda sin ningún parámetro. Sin embargo, al igual que los métodos, las expresiones lambda también pueden tener parámetros. Por ejemplo,

(n) -> (n%2)==0

Aquí, la variable n dentro del paréntesis es un parámetro pasado a la expresión lambda. El cuerpo lambda toma el parámetro y comprueba si es par o impar.

Ejemplo 4:uso de la expresión lambda con parámetros

@FunctionalInterface
interface MyInterface {

    // abstract method
    String reverse(String n);
}

public class Main {

    public static void main( String[] args ) {

        // declare a reference to MyInterface
        // assign a lambda expression to the reference
        MyInterface ref = (str) -> {

            String result = "";
            for (int i = str.length()-1; i >= 0 ; i--)
            result += str.charAt(i);
            return result;
        };

        // call the method of the interface
        System.out.println("Lambda reversed = " + ref.reverse("Lambda"));
    }

}

Salida :

Lambda reversed = adbmaL

Interfaz funcional genérica

Hasta ahora hemos utilizado la interfaz funcional que acepta solo un tipo de valor. Por ejemplo,

@FunctionalInterface
interface MyInterface {
    String reverseString(String n);
}

La interfaz funcional anterior solo acepta String y devuelve String . Sin embargo, podemos hacer que la interfaz funcional sea genérica, de modo que se acepte cualquier tipo de datos. Si no está seguro acerca de los genéricos, visite Java Generics.

Ejemplo 5:interfaz funcional genérica y expresiones lambda

// GenericInterface.java
@FunctionalInterface
interface GenericInterface<T> {

    // generic method
    T func(T t);
}

// GenericLambda.java
public class Main {

    public static void main( String[] args ) {

        // declare a reference to GenericInterface
        // the GenericInterface operates on String data
        // assign a lambda expression to it
        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"));

        // declare another reference to GenericInterface
        // the GenericInterface operates on Integer data
        // assign a lambda expression to it
        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));
    }
}

Salida :

Lambda reversed = adbmaL
factorial of 5 = 120

En el ejemplo anterior, hemos creado una interfaz funcional genérica llamada GenericInterface . Contiene un método genérico llamado func() .

Aquí, dentro de la clase Principal,


Expresión Lambda y API de transmisión

El nuevo paquete java.util.stream se ha agregado a JDK8, lo que permite a los desarrolladores de Java realizar operaciones como buscar, filtrar, mapear, reducir o manipular colecciones como Lists .

Por ejemplo, tenemos un flujo de datos (en nuestro caso, un List de String ) donde cada cadena es una combinación del nombre del país y el lugar del país. Ahora, podemos procesar este flujo de datos y recuperar solo los lugares de Nepal.

Para esto, podemos realizar operaciones masivas en la transmisión mediante la combinación de Stream API y Lambda expression.

Ejemplo 6:Demostración del uso de lambdas con Stream API

import java.util.ArrayList;
import java.util.List;

public class StreamMain {

    // create an object of list using ArrayList
    static List<String> places = new ArrayList<>();

    // preparing our data
    public static List getPlaces(){

        // add places and country to the list
        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));
    }

}

Salida :

Places from Nepal:
NEPAL, KATHMANDU
NEPAL, POKHARA

En el ejemplo anterior, observe la declaración,

myPlaces.stream()
        .filter((p) -> p.startsWith("Nepal"))
        .map((p) -> p.toUpperCase())
        .sorted()
        .forEach((p) -> System.out.println(p));

Aquí, estamos usando métodos como filter() , map() y forEach() de la API de transmisión. Estos métodos pueden tomar una expresión lambda como entrada.

También podemos definir nuestras propias expresiones en función de la sintaxis que aprendimos anteriormente. Esto nos permite reducir drásticamente las líneas de código como vimos en el ejemplo anterior.


Java

  1. interfaz C#
  2. Operadores Java
  3. Expresiones, declaraciones y bloques de Java
  4. Interfaz Java
  5. Prueba de Java con recursos
  6. Anotaciones Java
  7. Interfaz vs clase abstracta en Java:¿cuál es la diferencia?
  8. Java - Expresiones regulares
  9. Java - Interfaces
  10. Java 9 - Métodos de interfaz privada
  11. Java 8 - Expresiones lambda