variable type practices parameter lambdas functional expressions example best java lambda java-8

type - Java 8, Lambda: reemplaza la clase interna anónima por lambda



lambda expressions java 8 example (3)

Tengo una clase que contiene lo siguiente:

List roles = ldapTemplate.search(baseDn, replaceFilter, sc, new AttributesMapper() { public Object mapFromAttributes(Attributes attrs) throws NamingException { return attrs.get("cn").get(); } });

IntelliJ me dice que reemplace la clase interna anónima con un lambda. Así que intenté:

List roles = ldapTemplate.search( baseDn, replaceFilter, sc, (Attributes a) -> { return a.get("cn").get(); }; );

Sin embargo, me sale un error de compilación:

Error:(46, 50) java: incompatible types: inference variable T has incompatible bounds equality constraints: java.lang.String lower bounds: java.lang.Object

No puedo encontrar la solución a este problema. ¿Tienes alguna idea?


Prueba esto (eliminando el punto y coma extra)

List roles = ldapTemplate.search( baseDn, replaceFilter, sc, (Attributes a) -> { return a.get("cn").get(); } );


Tengo la fuerte sensación de que no publicó el código exacto en su pregunta. Al igual que Bart , no puedo reproducir el error con el código como has publicado.

Sin embargo, lo que me sorprende es su uso de tipos crudos . Si su código original se veía así:

List<String> roles = ldapTemplate.search(baseDn, replaceFilter, sc, new AttributesMapper() { public Object mapFromAttributes(Attributes attrs) throws NamingException { return attrs.get("cn").get(); } });

(tenga en cuenta el tipo modificado de la variable de roles ) que saldría con solo una advertencia de tipo sin formato al implementar AttributesMapper sin argumentos de tipo y no se verificará si el Object devuelto será válido como elemento para una List<String> .

Al convertir ese código en un lambda, ya no puede salirse con la suya:

List<String> roles = ldapTemplate.search(baseDn, replaceFilter, sc, (Attributes a) -> { return a.get("cn").get(); } );

Ahora, el compilador deducirá el tipo AttributesMapper<String> y producirá un error porque su expresión lambda devuelve Object lugar de String y, por lo tanto, no cumple con la interfaz AttributesMapper<String> .

Puede solucionarlo insertando una conversión de tipos para cumplir con la interfaz AttributesMapper<String> o declarando roles con la List tipos sin List como ya hizo en la pregunta. Sin embargo, usar el modelo moldeado será la forma más limpia (y debería ser la única que no produzca advertencias del compilador):

List<String> roles = ldapTemplate.search(baseDn, replaceFilter, sc, a -> (String)a.get("cn").get());

(Simplifiqué la expresión para compensar el tipo de conversión incluido, se ve mucho mejor, ¿no?)


Una interfaz de resolución de entidades de almacenamiento de Azure simple y su método implementado:

EntityResolver<String> orderNumberResolver = new EntityResolver<String>() { @Override public String resolve(String partitionKey, String rowKey, Date timeStamp, HashMap<String, EntityProperty> properties, String etag) { return properties.get("SomeColumnName").getValueAsString(); } };

Lambda del método anterior será:

EntityResolver<String> orderNumberResolver = ( partitionKey, rowKey, timeStamp, properties, etag ) -> properties.get("SomeColumnName").getValueAsString();

De acuerdo con el ejemplo anterior, queda claro que los lambda son lo suficientemente inteligentes para manejar el tipo de parámetros del método de acuerdo con su clase interna anónima, lo que facilita la implementación del método anulado. Esperamos que esto sea útil.