¿Cómo se asigna una lambda a una variable en Java 8?

3 minutos de lectura

Solo estoy jugando con el nuevo lambda y las funciones funcionales en Java 8 y no estoy seguro de cómo hacerlo.

Por ejemplo, lo siguiente es válido:

    Map<String, Integer> map = new HashMap<>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 3);
    map.compute("A", (k, v) -> v == null ? 42 : v + 41));

pero lo siguiente me da errores de sintaxis:

    BiFunction x = (k, v) -> v == null ? 42 : v + 41;
    map.compute("A", x);

¿Algunas ideas?

  • Por favor, publique los errores de sintaxis reales.

    – JBCP

    20 de febrero de 2014 a las 21:46

Ha olvidado los genéricos en su BiFunction:

public static void main(final String[] args) throws Exception {
    final Map<String, Integer> map = new HashMap<>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 3);
    final BiFunction<String, Integer, Integer> remapper = (k, v) -> v == null ? 42 : v + 41;
    map.compute("A", remapper);
}

Correr:

PS C:\Users\Boris> java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b120)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b62, mixed mode)

  • Fresco. Ya veo, necesito ser muy explícito al respecto. Cuando mira el tipo de parámetro cuando mira el método map.compute, solo lo muestra como BiFunction solo.

    – piñón

    20 de febrero de 2014 a las 21:48

  • La inferencia de tipos de Java 8 ha mejorado significativamente con respecto a las versiones anteriores, aún necesita especificar los tipos genéricos al comienzo de una expresión para que el compilador trabaje. Si miras el Javadoc para Map puede ver los tipos requeridos.

    – Boris la araña

    20 de febrero de 2014 a las 21:52


  • Tenga en cuenta que “final” no es obligatorio. Se compila bien sin eso. No estoy seguro si eso es un error o una característica.

    – piñón

    20 de febrero de 2014 a las 21:58

  • @sproketboy en versiones anteriores de Java final era necesario para que una variable local fuera accesible en una clase anónima. En Java 8 esto ha cambiado, el requisito ahora es que la variable sea “efectivamente definitiva”, es decir, si el compilador determina que la variable no se reasigna. Así que característica…

    – Boris la araña

    20 de febrero de 2014 a las 22:09


  • Su ejemplo no usa reasignador en un AIC o en un lambda, por lo que ni siquiera necesita ser efectivamente final. podrías quitar final de la declaración y reasignar el reasignador a otra cosa más tarde y aún funcionaría.

    – Marcas de Stuart

    21 de febrero de 2014 a las 2:04

Avatar de usuario de JBCP
JBCP

Como señala Boris The Spider, el problema específico que tienes son los genéricos. Según el contexto, agregar un bloque {} explícito alrededor de la lambda ayudará a agregar claridad y puede ser necesario.

Con eso, obtendrías algo como:

BiFunction<String, Integer, Integer> x = (String k, Integer v) -> {v == null ? 42 : v + 41};

Sería muy útil para futuros lectores que tengan el mismo problema si publicara sus errores de sintaxis para que puedan indexarse.

Este enlace tiene algunos ejemplos adicionales que podrían ayudar.

  • Esto no está del todo bien, mira mi respuesta. BiFunction toma 3 tipos de argumentos.

    – Boris la araña

    20 de febrero de 2014 a las 21:43

ejemplo de pasar una lambda que contiene un método

YourClass myObject = new YourClass();

// first parameter, second parameter and return 
BiFunction<String, YourClass, String> YourFunction; 

YourFunction = (k, v) -> v == null ? "ERROR your class object is null" : defaultHandler("hello",myObject);

public String defaultHandler(String message, YourClass Object)
{
     //TODO ...

     return "";
}

¿Ha sido útil esta solución?