lambda - example - cómo usar opcional y filtrar para recuperar un objeto de objetos encadenados/en cascada generados por wsdl2java
optional lambda java (2)
Entiendo que se recomienda flatMap cuando se trata de objetos jerárquicos en Java, particularmente al extraer valores de objetos creados a partir de archivos XML.
Sin depender de Opcional y dado que getCommerleleNaam () me traerá una lista, codifiqué:
NaamOndernemingLijstCommercieelType naamOndernemingLijstCommercieel = onderneming.getNamen()
.getCommercieleNamen();
NaamOndernemingType naamOndernemingType = naamOndernemingLijstCommercieel.getCommercieleNaam().stream()
.filter(x -> x.getTaalcode().getValue() == "nl").findFirst().get();
En pocas palabras, caminará arrojando el objeto en cascada y devolverá el primer nombre encontrado para el idioma de Holanda. Veo esto como muy inseguro y, en lugar de verificar todos los objetos si son nulos, prefiero usar Opcional.
Luego intento codificar lo que entiendo que es la forma correcta, pero no sé cómo aplicar filtro para recuperar solo el objeto de la lista que coincida con un criterio (lenguaje == "nl" en mi escenario):
Optional<NamenOndernemingType> optionalNamenOnderneming = onderneming.getNamen();
NaamOndernemingType naamOndernemingType = optionalNamenOnderneming.flatMap(NamenOndernemingType::getCommercieleNamen)
.flatMap(NaamOndernemingLijstCommercieelType::getCommercieleNaam)
.filter(x -> "nl".equals(x.toString()));
PD .: en holandés, naam significa nombre (singular) y Namen significa nombre (plural)
Bueno, lo más cercano que tengo es
Optional<NamenOndernemingType> optionalNamenOnderneming = Optional.ofNullable(onderneming.getNamen());
List<NaamOndernemingType> listNaamOndernemingType = optionalNamenOnderneming
.flatMap(NamenOndernemingType::getCommercieleNamen)
.map(NaamOndernemingLijstCommercieelType::getCommercieleNaam);
Pero tampoco funciona y luego de arreglar esto, necesito filtrar también.
* editado
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NamenOndernemingType", propOrder = {
"maatschappelijkeNamen",
"afgekorteNamen",
"commercieleNamen"
})
public class NamenOndernemingType {
...
public NaamOndernemingLijstCommercieelType getCommercieleNamen() {
return commercieleNamen;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NaamOndernemingLijstCommercieelType", propOrder = {
"commercieleNaam"
})
public class NaamOndernemingLijstCommercieelType {
...
public List<NaamOndernemingType> getCommercieleNaam() {
* Solución *
Optional.ofNullable(onderneming.getNamen()).map(NamenOndernemingType::getCommercieleNamen)
.map(NaamOndernemingLijstCommercieelType::getCommercieleNaam).get().stream().filter(Objects::nonNull)
.filter(x -> x.getTaalcode().getValue() == "nl").findFirst()
.ifPresent(o -> myMethod("onderneming_commerciele_naam", o.getNaam().getValue()));
PD: los lectores futuros mi hallazgo vale la pena leer mi otra pregunta como weel: cómo usar Opcional con objetos en cascada no creados con Opcional
Gracias a las recomendaciones de Aominè ya la discusión basada en cómo el uso Opcional con objetos en cascada no creados con Opcional
Llegué a esta solución:
Optional.ofNullable(onderneming.getNamen()).map(NamenOndernemingType::getCommercieleNamen)
.map(NaamOndernemingLijstCommercieelType::getCommercieleNaam).get().stream().filter(Objects::nonNull)
.filter(x -> x.getTaalcode().getValue() == "nl").findFirst()
.ifPresent(o -> myMethod("onderneming_commerciele_naam", o.getNaam().getValue()));
No creo que necesites un mapa aquí, ya que has dicho que getCommercieleNaam
devuelve una List<NaamOndernemingType>
por lo tanto, una vez que Stream<NaamOndernemingType>
tendremos un Stream<NaamOndernemingType>
que luego podemos encontrar todos los objetos que tienen "nl"
como su representación de cadena
List<NaamOndernemingType> listNaamOndernemingType = optionalNamenOnderneming
.flatMap(NaamOndernemingLijstCommercieelType::getCommercieleNaam)
.filter(Objects::nonNull)
.filter(x -> "nl".equals(x.toString()))
.orElse(null);
dado que un Optional
no tiene collect
como una operación de terminal , simplemente podemos usar orElse
para devolver el valor si está presente; de lo contrario, devolveremos el valor null
. en este caso, el valor es una List<NaamOndernemingType>
.
nota: solo necesitarás llamar a flatMap si quieres cambiar un Stream<Stream<R>>
a un Stream<T>
contrario, solo quieres una llamada al mapa que devuelva un Stream<R>
.