Cześć załóżmy, że mam następującą sytuację:
Optional<User> user = userService.getUserById(1);
i następnie chcę wziąć wszystkie konta tego usera. Załóżmy, że user ma metodę getTransactions
, która zwraca Set<Optional<Transaction>>
oraz Transaction
posiada metodę Optional<Iban> getIban
.
Robię to w następując sposób:
List<Iban> ibans= user // Optional<User>
.map(u::getTransactions()) // Optional<Set<Optional<Transaction>>> nie mogę użyć flatMap bo zadziała na Set
.map(Collection::stream) // Optional<Stream<Optional<Transaction>>>
.map(str -> str
.filter(Optional::isPresent) // Stream<Optional<Transaction>>
.map(Optional::get) // Stream<Transaction>
.map(Transaction::getIban) // Stream<Optional<Iban>>
.filter(Optional::isPresent) // Stream<Optional<Iban>>
.map(Optional::get) // Stream<Iban>
.collect(Collectors.toSet())
).orElse(Collections.emptySet());
Mój kod nie podoba mi się z kilku względów:
- mapowanie na
stram
- zagnieżdżone przetwarzanie
map
- naprzemienne
get
iisPresent
Jak można radzić sobie w takich przypadkach?
EDIT:
Tą część mogę oczywiście wyciągnąć do lambdy, ale to nie rozwiązuje większości bolączek tego kodu.
.filter(Optional::isPresent) // Stream<Optional<Transaction>>
.map(Optional::get) // Stream<Transaction>
.map(Transaction::getIban) // Stream<Optional<Iban>>
.filter(Optional::isPresent) // Stream<Optional<Iban>>
.map(Optional::get) // Stream<Iban>
.collect(Collectors.toSet())