Próbuję zrozumieć ifPresent()
metodę Optional
API w Javie 8.
Mam prostą logikę:
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
Ale to powoduje błąd kompilacji:
ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)
Oczywiście mogę zrobić coś takiego:
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
Ale to jest dokładnie jak zagracony null
czek.
Jeśli zmienię kod na ten:
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
Kod staje się brudniejszy, co sprawia, że myślę o powrocie do starego null
czeku.
Jakieś pomysły?
user.ifPresent(this::doSomethingWithUser);
Optional<User>
często nie ma potrzeby przechowywania jej w zmiennej lokalnej. Po prostu połącz wywołania metody:funcThatMightReturnUser().ifPresent(this::doSomethingWithUser);
Oprócz odpowiedzi @ JBNizet, moim ogólnym przypadkiem użycia
ifPresent
jest połączenie.isPresent()
i.get()
:Stara droga:
Optional opt = getIntOptional(); if(opt.isPresent()) { Integer value = opt.get(); // do something with value }
Nowy sposób:
Optional opt = getIntOptional(); opt.ifPresent(value -> { // do something with value })
Dla mnie jest to bardziej intuicyjne.
źródło
Po co pisać skomplikowany kod, skoro można to uprościć?
Rzeczywiście, jeśli absolutnie zamierzasz używać tej
Optional
klasy, najprostszym kodem jest to, co już napisałeś ...if (user.isPresent()) { doSomethingWithUser(user.get()); }
Ten kod ma zalety bycia
To, że Oracle dodała
Optional
klasę w Javie 8, nie oznacza, że ta klasa musi być używana w każdej sytuacji.źródło
Użyj flatMap. Jeśli wartość jest obecna, flatMap zwraca sekwencyjny Stream zawierający tylko tę wartość, w przeciwnym razie zwraca pusty Stream. Więc nie ma potrzeby używania
ifPresent()
. Przykład:list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());
źródło
Możesz użyć odwołania do metody w następujący sposób:
Metoda
ifPresent()
getConsumer
object jako parometr i (z JavaDoc ): "Jeśli wartość jest obecna, wywołaj określonego konsumenta z wartością." Wartość to twoja zmiennauser
.Lub jeśli ta metoda
doSomethingWithUser
znajduje się wUser
klasie, a tak nie jeststatic
, możesz użyć odwołania do metody w następujący sposób:user.ifPresent(this::doSomethingWithUser);
źródło
user.ifPresent(new ClassNameWhereMethodIs()::doSomethingWithUser);
user.ifPresent(this::doSomethingWithUser);
user.ifPresent(this::doSomethingWithUser);
. Dodam to do mojej odpowiedzi.