2017-01-05 28 views
5

Próbuję zrobić coś takiego:Java 8 opcjonalnie: ifPresent obiekt powrót orElseThrow wyjątek

private String getStringIfObjectIsPresent(Optional<Object> object){ 
     object.ifPresent(() ->{ 
      String result = "result"; 
      //some logic with result and return it 
      return result; 
     }).orElseThrow(MyCustomException::new); 
    } 

to nie będzie działać, ponieważ ifPresent trwa Consumer funkcjonalny interfejs jako parametr, który ma przyjąć void (T t). Nie może zwrócić żadnej wartości. Czy jest jakiś inny sposób na zrobienie tego?

+0

Możliwe duplikat [Właściwe użycie Optional.ifPresent()] (http://stackoverflow.com/questions/24228279/proper-usage-of-optional-ifpresent) –

Odpowiedz

7

wolałbym mapowanie po upewnieniu się, że wartość ta jest dostępny

private String getStringIfObjectIsPresent(Optional<Object> object) { 
    Object ob = object.orElseThrow(MyCustomException::new); 
    // do your mapping with ob 
    String result = your-map-function(ob); 
    return result; 
} 

lub jedna wkładka

private String getStringIfObjectIsPresent(Optional<Object> object) { 
    return your-map-function(object.orElseThrow(MyCustomException::new)); 
} 
+0

Faktycznie 'Optional.map' sprawdza, czy obiekt jest dostępny przed wywołaniem przekazanej funkcji mapowania. Ale przynajmniej oszczędzasz 1 warunek ('value! = Null') w ten sposób. – Roland

4

Zamiast tego użyj funkcji map. Przekształca wartość w opcjonalnym.

Jak to:

private String getStringIfObjectIsPresent(Optional<Object> object) { 
    return object.map(() -> { 
     String result = "result"; 
     //some logic with result and return it 
     return result; 
    }).orElseThrow(MyCustomException::new); 
} 
11

Właściwie, czego szukasz jest: Optional.map. Twój kod będzie wtedy wyglądać tak:

object.map(o -> "result" /* or your function */) 
     .orElseThrow(MyCustomException::new); 

wolałbym należy pominąć minięciu Optional jeśli możesz. W końcu nic nie zyskujesz, używając tutaj Optional. Nieco inny wariant:

public String getString(Object yourObject) { 
    if (Objects.isNull(yourObject)) { // or use requireNonNull instead if NullPointerException suffices 
    throw new MyCustomException(); 
    } 
    String result = ... 
    // your string mapping function 
    return result; 
} 

Jeśli masz już Optional -przedmiot powodu innej rozmowy, chciałbym jeszcze polecić można użyć map -method zamiast isPresent itp dla pojedynczego powodu, że jest bardziej czytelny (wyraźnie subiektywna decyzja ;-)).

2

dwie możliwości:

Wymień ifPresent z map i używają Function zamiast Consumer

private String getStringIfObjectIsPresent(Optional<Object> object) { 
    return object 
      .map(obj -> { 
       String result = "result"; 
       //some logic with result and return it 
       return result; 
      }) 
      .orElseThrow(MyCustomException::new); 
} 

Stosować isPresent:

private String getStringIfObjectIsPresent(Optional<Object> object) { 
    if (object.isPresent()) { 
     String result = "result"; 
     //some logic with result and return it 
     return result; 
    } else { 
     throw new MyCustomException(); 
    } 
}