java lambda java-8

java - ''Regla especial de compatibilidad de vacíos'' de Lambda-expresión de declaración



java-8 (3)

El término "expresión de declaración" o "declaración de expresión" se refiere a expresiones que también se pueden utilizar como una declaración. Se describen en la Especificación del lenguaje Java, §14.8. Declaraciones de expresión .

Incluyen:

  • Invocaciones de métodos
  • Asignaciones
  • Expresiones de incremento / decremento
  • Expresiones de creación de instancia de clase

Entonces otros ejemplos son:

Consumer<String> b = s -> counter++; Function<String,Integer> f = s -> counter++;

o

Consumer<String> b = s -> new BigDecimal(s); Function<String,BigDecimal> f = s -> new BigDecimal(s);

Como regla general, una expresión lambda de la forma x -> expression solo es legal para un Consumer (o tipo de función void en general), si x -> { expression; } x -> { expression; } sería legal también.

Estoy leyendo Java 8 en acción. En la sección 3.5.2 hay un párrafo sobre ''regla de compatibilidad nula'':

Si una lambda tiene una expresión de declaración como cuerpo, es compatible con un descriptor de función que devuelve void (siempre que la lista de parámetros también sea compatible). Por ejemplo, las dos líneas siguientes son legales aunque el método add de una Lista devuelve un valor booleano y no nulo como se esperaba en el contexto del Consumidor (T -> nulo):

// Predicate has a boolean return Predicate<String> p = s -> list.add(s); // Consumer has a void return Consumer<String> b = s -> list.add(s);

¿Cómo describirías ''expresión de declaración'' en general? Pensé que era una declaración o una expresión. Además, esta regla de compatibilidad nula no es 100% clara para mí, ¿puedes pensar en algún otro ejemplo?


Está explicado en la publicación anterior claramente ... ¡Estoy intentando en mi camino!

Se puede proporcionar un descriptor de función con un valor de retorno explícito para un descriptor de función lambda que no devuelve ningún valor.

Por ejemplo, Predicate T -> vs Consumer T -> void lambda expression que toma una entrada y da booleano como retorno, Predicate, puede ser suministrado para Consumer.

En el siguiente ejemplo, public boolean add (E e) {} devuelve boolean, pero puede usarse en lambda para Consumer, que devuelve void.

Predicate<String> p = s -> list.add(s); p.test("helloworld"); // this returns boolean Consumer<String> consumerExample = s -> list.add(s); consumerExample.accept("Welcometokpm"); // this returns void


La estructura común de la expresión lambda es que:

(parameter) -> {body};

{body} con una declaración de retorno de una sola línea es opcional, por ejemplo

Predicate<String> p = s -> list.add(s);

Cuando se utilizan llaves, la declaración de devolución se vuelve obligatoria, por ejemplo

Predicate<String> p = s -> { return list.add(s);};

Ahora, considere una interfaz funcional como Consumer con un método abstracto que no devuelve ningún valor. Puede aceptar una declaración que devuelva cualquier valor porque el compilador ignora la declaración de retorno para dichos métodos abstractos.

Y por lo tanto, las siguientes afirmaciones son verdaderas:

Consumer<String> b = s -> list.add(s);

Equivalente a:

Consumer<String> consumerExample = s -> {list.add(s);};

La siguiente línea es incorrecta:

Consumer<String> consumerExample = s -> {return list.add(s);};

Por lo tanto, si una lambda tiene una expresión de declaración como su cuerpo, es compatible con un descriptor de función que devuelve void (siempre que la lista de parámetros también sea compatible) .