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?
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
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 "";
}
Por favor, publique los errores de sintaxis reales.
– JBCP
20 de febrero de 2014 a las 21:46