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.