Java 8 wyszukiwanie w mapie

0

Witam,
mam oto takie pole które reprezentuje JSON'a
private List<Map<String, Map<String, Map<String, Object>>>> description;

Teraz potrzebuje wyszukać w tej strukturze wszystkie obiekty optionId, które znajdują się na 3 poziomie tej mapy
componentDefinitionModel -> componentsDef -> optionId.

Jednak ta mapa zawiera też inne elementy więc mogą się zdarzyć nulle. Jak to rozwiązać najlepiej, z aktualnego rozwiązania nie jestem zadowolony, dużo powtarzania jak usunąć te linie .filter(Optional::isPresent).map(Optional::get)

description.stream()
				.map(map -> Optional.ofNullable((map.get("componentDefinitionModel"))))
				.filter(Optional::isPresent).map(Optional::get)
				.map(map -> Optional.ofNullable((map.get("componentsDef"))))
				.filter(Optional::isPresent).map(Optional::get)
				.map(map -> Optional.ofNullable(map.get("optionId")))
				.filter(Optional::isPresent).map(Optional::get)
				.forEach(System.out::println);
0

Ale przecież Optional ma swoją metodę map() która robi dokładnie to co byś chciał, tzn wykonuje akcje tylko jeśli optional nie jest pusty.

0

Dalej kiepsko wynikiem

		Stream<Optional<Object>> stream = description.stream().map(
				map -> Optional.ofNullable(
						(map.get("componentDefinitionModel"))).map(
						componentDefinitionModel -> Optional
								.ofNullable(
										(componentDefinitionModel
												.get("componentsDef"))).map(
										componentsDef -> Optional
												.ofNullable(componentsDef
														.get("optionId")))));

		stream.forEach(System.out::println);

jest

Optional[Optional[Optional[finded1]]]]
Optional[Optional[Optional[finded2]]]]
Optional[Optional[Optional[finded3]]]]
1

Użyj flatMap, który zamiast opakowania w kolejny Optional oczekuje funkcji, która zwróci Optional. W efekcie zamiast Optional[Optional[T]] otrzymasz Optional[T].

//edit:

Nie potrzebujesz zagłębiać wywołań:

Stream.flatmap(map-> Optional.ofNullable(...)).flatmap(map-> Optional.ofNullable(...))....

jest zdecydowanie lepsze.

0

Końcowa postać oki

		Stream<Object> stream = description
				.stream()
				.map(map -> Optional.ofNullable(map.get("componentDefinitionModel"))
						.map(componentDefinitionModel -> componentDefinitionModel.get("componentsDef"))
						.map(componentsDef -> componentsDef.get("optionId"))).filter(Optional::isPresent).map(Optional::get).forEach(System.out::println);

		

1 użytkowników online, w tym zalogowanych: 0, gości: 1