2015-08-28 20 views
10

Così Attualmente hoSepara un optional solo se è presente

String uri = website.getUri(); 
Optional<PageDetail> pageDetail = webClient.getDetailOfUri(uri); 
String displayName; 
String description; 
if (pageDetail.isPresent()) { 
    displayName = pageDetail.get().getName(); 
    description = pageDetail.get().getDescription(); 
} else { 
    displayName = uri; 
    description = ""; 
} 

sto chiamando il metodo getDetailOfUri(uri), che restituisce un Optional<PageDetail>, e vorrei per impostare le corde displayName e description ai valori della PageDetail campi dell'oggetto, se presente. Altrimenti, vorrei impostarlo su alcuni valori predefiniti.

La mia domanda è, c'è un modo migliore per riscrivere questo? Il mio codice attuale sembra un po 'lungo e noioso, e mi piacerebbe sapere se c'è un modo più conciso per farlo.

+1

oltre a utilizzare "bool? IfTrue: ifFalse" Non lo vedo –

+0

Sì, la dichiarazione ternaria non è un'opzione. – yiwei

risposta

13

si potrebbe scrivere:

String uri = website.getUri(); 
Optional<PageDetail> pageDetail = webClient.getDetailOfUri(uri); 
String displayName = pageDetail.map(PageDetail::getName).orElse(uri); 
String description = pageDetail.map(PageDetail::getDescription).orElse(""); 

Se il Optional non è impostato, map tornerà lo stesso non impostato Optional. In caso contrario, verrà mappato a un Optional contenente il risultato di getName(). Quindi possiamo usare orElse per restituire un valore predefinito quando Optional non è impostato.

+0

Grazie! Sono ancora molto nuovo per i lamda di Java 8, quindi mi sto concedendo un po 'di tempo per completare questo. Ma questo sembra quello di cui ho bisogno! – yiwei

+0

@Andreas my 'getName()'/'PageDetail' non è definitivo, ma' p' è garantito che non sia una sottoclasse di 'PageDetail. Quindi dovrebbe funzionare, giusto? – yiwei

+0

Non mi piace questa risposta perché se PageDetail ha più di 2 campi (displayName e descrizione), avrai molte chiamate map(). OElse. Preferisco avere un'istanza di fallback e lavorare con un'istanza non facoltativa da lì. – pyb

8

Uso Optional#orElseGet che prende un Supplier:

// Reference to the constructor, but you could use a Factory, etc. 
// All you need is a method that returns a PageDetail 
// See the Javadoc and http://www.byteslounge.com/tutorials/java-8-consumer-and-supplier 
Supplier<PageDetail> emptySupplier = PageDetail::new; 

pageDetail = pageDetail.orElseGet(emptySupplier); 
// works the same 
//pageDetail = pageDetail.orElseGet(() -> new PageDetail()); 

String displayname = pageDetail.getName(); 
String uri = pageDetail.getUri(); 

orElseGet creerà un PageDetail vuota solo se l'opzionale ha un valore nullo. Ciò mantiene efficiente il tuo codice di risorse.

campione compilabile/modificabile: https://ideone.com/9h1Ntg

Edit: Grazie a tutti per il feedback! In realtà stavo aggiungendo orElseGet che trovo meglio. Ho anche corretto il codice per scartare lo Optional in modo che pageDetail termini come un'istanza effettiva PageDetail.

Modifica 2: Aggiunto un esempio di sintassi diverso ed esempio modificabile/compilabile.

+2

No, questo è sbagliato perché è necessario chiamare 'getName()' per ottenere il nome visualizzato. – Tunaki

+0

oElse (T altro), non oElseGet (fornitore altro) – leoger

+0

@Tunaki, non sto capendo il tuo commento. Puoi chiarire? – leoger

Problemi correlati