2015-02-19 7 views
19

Diciamo che voglio vedere se un oggetto esiste in uno stream e se non è presente, lanciare un'eccezione. Un modo ho potuto fare che sarebbe utilizzando il metodo orElseThrow:Lanciare un'eccezione se è presente un <> opzionale

List<String> values = new ArrayList<>(); 
values.add("one"); 
//values.add("two"); // exception thrown 
values.add("three"); 
String two = values.stream() 
     .filter(s -> s.equals("two")) 
     .findAny() 
     .orElseThrow(() -> new RuntimeException("not found")); 

Che dire in contrario? Se voglio un'eccezione se una partita viene trovato:

String two = values.stream() 
     .filter(s -> s.equals("two")) 
     .findAny() 
     .ifPresentThrow(() -> new RuntimeException("not found")); 

ho potuto solo memorizzare il Optional, e fare la isPresent controllo dopo:

Optional<String> two = values.stream() 
     .filter(s -> s.equals("two")) 
     .findAny(); 
if (two.isPresent()) { 
    throw new RuntimeException("not found"); 
} 

Esiste un modo per raggiungere questo obiettivo ifPresentThrow sorta di comportamento? Sta provando a buttare in questo modo una cattiva pratica?

+3

il punto di 'orElseThrow' è quello di convertire il valore a un non-optional con la gestione degli errori se il valore non esiste. Poiché tutto ciò che ti interessa è se il valore esiste, perché non utilizzare il metodo progettato per questo scopo: 'isPresent'? –

risposta

15

Dal momento che vi interessa soltanto se è stata trovata una corrispondenza, non è ciò che è stato effettivamente trovato, è possibile utilizzare anyMatch per questo, e non è necessario utilizzare Optional affatto:

if (values.stream().anyMatch(s -> s.equals("two"))) { 
    throw new RuntimeException("two was found"); 
} 
+10

o '.anyMatch (" two ":: equals)' – Misha

+5

@Misha: questo è uno dei rari casi in cui l'espressione lambda è più efficiente perché non cattura qualsiasi valore (come '" two "' è una costante in fase di compilazione). Al contrario, il riferimento al metodo acquisirà sempre l'istanza su cui il metodo deve essere invocato. – Holger

+0

So che @Holger ha ragione, ma devo ammettere che @ Misha "due" :: equals' è una sintassi molto bella. È difficile dire no a questo per ottenere alcuni nonosec di prestazioni :-) –

18

è possibile utilizzare la chiamata ifPresent() ad un'eccezione se il filtro trova nulla:

values.stream() 
      .filter("two"::equals) 
      .findAny() 
      .ifPresent(s -> { 
       throw new RuntimeException("found"); 
      }); 
+0

Non può essere lanciato nel metodo ifPresent. – jeon

+1

Sì, può - eseguire quanto segue. 'Optional.of (1) .ifPresent (s -> {lancia nuova RuntimeException (" oh guarda un'eccezione ");});' – beresfordt

+0

Solo RuntimeException può essere lanciato in questo modo – zmark

Problemi correlati