2015-02-19 4 views
19

Angenommen, ich möchte sehen, ob ein Objekt in einem Stream vorhanden ist und, wenn es nicht vorhanden ist, eine Ausnahme auslösen. Eine Möglichkeit, die ich tun könnte, würde mit der orElseThrow Methode:Eine Ausnahme auslösen, wenn ein Optional <> vorhanden ist

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")); 

Was ist in der Rückseite? Wenn ich will, um eine Ausnahme auszulösen, wenn eine Übereinstimmung gefunden wird:

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

Ich konnte nur die Optional speichern und tun die isPresent Prüfung nach:

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

Gibt es eine Möglichkeit, diese ifPresentThrow Art zu erreichen von Verhalten? Versucht man auf diese Weise eine schlechte Übung zu werfen?

+3

der Punkt 'orElseThrow' ist, den Wert zu einem nicht optional konvertieren mit Fehlerbehandlung, wenn der Wert nicht vorhanden ist. Da Sie nur daran interessiert sind, ob der Wert existiert, warum sollten Sie nicht die für diesen Zweck entwickelte Methode verwenden: 'isPresent'? –

Antwort

15

Da Sie nur Pflege wenn eine Übereinstimmung gefunden wurde, nicht das, was tatsächlich gefunden wurde, können Sie anyMatch für dies, und Sie brauchen nicht Optional überhaupt zu benutzen:

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

oder '.anyMatch (" zwei ":: gleich)' – Misha

+5

@Misha: Dies ist einer der seltenen Fälle, wo der Lambda-Ausdruck effizienter ist, weil es nicht erfasst irgendwelche Werte (als '" zwei "' ist eine Kompilierzeitkonstante). Im Gegensatz dazu erfasst die Methodenreferenz immer die Instanz, auf der die Methode aufgerufen werden soll. – Holger

+0

Ich weiß, @Holger hat Recht, aber ich muss zugeben, dass @ Misha '' zwei ":: gleich ist eine sehr schöne Syntax. Es ist schwer, nein zu sagen, um ein paar Nonosecs Leistung zu bekommen :-) –

18

könnten Sie verwenden den ifPresent() Aufruf eine Ausnahme ausgelöst, wenn Sie einen Filter, alles findet:

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

Es kann nicht in ifPresent Methode geworfen werden. – jeon

+1

Ja kann es - führen Sie Folgendes aus. 'Optional.of (1) .ifPresent (s -> {neue RuntimeException auslösen (" oh, sehe eine Ausnahme aus ");});' – beresfordt

+0

Nur RuntimeException kann auf diese Weise ausgelöst werden – zmark

Verwandte Themen