2015-09-30 8 views
6

Na przykład dla tego kodu:Jaki jest właściwy sposób sprawdzania wartości null lub sprawdzania wyjątków w łańcuchowej instrukcji w języku Java 8?

List<Class> classes = 
     Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String") 
       .map(className -> Class.forName(className)) 
       .collect(Collectors.toList()); 

Ten kod działa teraz prawidłowo. ale, zakładamy, że mamy pustą listę w strumieniu i mamy mnóstwo operacji do strumienia. Może uzyskać wyjątki NullPointer i inne. Uważam, że trudno jest też próbować złapać tego rodzaju wypowiedzi. Jaki jest właściwy sposób obsługi wyjątku?

+3

Co? Jeśli jest pusty, nic nie zostanie zastosowane. Próbuj złapać? Gdzie? Czemu? –

+1

co masz na myśli "pusta lista w strumieniu"? Twój strumień ma ciąg, a nie listę. Czy chodziło Ci o "null string in stream"? – Bohemian

Odpowiedz

7

Nie trzeba sprawdzać wartości zerowych. Jeśli masz pusty strumień wszystkie operacje zostaną pominięty:

Stream.of("hello") 
     .filter(e => "world".equals(e)) // empties the stream 
     .foreach(System.out::println); // no NullPointer, no output 

Obsługa wyjątków jest możliwe w odwzorowującym:

List<Class<?>> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String") 
      .map(className -> { 
       try { 
        return Class.forName(className); 
       } catch (Exception e) { 
        throw new YourRuntimeException(); 
       } 
      }) 
      .collect(Collectors.toList()); 

Jeśli chcesz wyjątki będą ignorowane, to proponuję, aby mapować do Optional s.

List<Class<?>> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String") 
      .map(className -> { 
       try { 
        return Optional.of(Class.forName(className)); 
       } catch (Exception e) { 
        return Optional.<Class<?>>empty(); 
       } 
      }) 
      .filter(Optional::isPresent) // ignore empty values 
      .map (Optional::get) // unwrap Optional contents 
      .collect(Collectors.toList()); 

Proszę również spojrzeć na How can I throw CHECKED exceptions from inside Java 8 streams? do bardziej szczegółowej dyskusji o Class.forName w połączeniu z Java 8 strumieni.

+2

Ani '=>'. Zauważ, że te trzy kroki, odwzorowanie na opcję "Opcjonalnie", filtrowanie za pośrednictwem opcji "Opcjonalnie.isPresent" i rozpakowanie opcji "Opcjonalnie" są niepotrzebnie skomplikowane. Pojedyncza 'flatMap' może wykonać operację. – Holger

4

Twoje pytanie jest nieco dziwne. Zgłaszasz roszczenie "Ten kod działa teraz dobrze", podczas gdy powinien generować błędy podczas kompilacji, ponieważ nie obsługujesz sprawdzonego wyjątku zadeklarowanego przez Class.forName. Dalej mówimy o pustych listach, ale w twoim kodzie nie ma żadnych list. To samo odnosi się do twojego odniesienia do NullPointerException, ponieważ twój kod nie produkuje null w żadnym miejscu.

Najprawdopodobniej chodzi o kod, który przechwytuje kod ClassNotFoundException i obsługuje go, zwracając null. Nigdy nie powinieneś tego robić. Jeśli chcesz odfiltrować awarie, można zrobić to w ten sposób:

List<Class<?>> classes = 
    Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String") 
     .flatMap(className -> { 
       try { 
        return Stream.of(Class.forName(className)); 
       } catch (ClassNotFoundException ex) { 
        // recommended: insert logging statement here 
        return Stream.empty(); 
       } 
      }) 
     .collect(Collectors.toList()); 

ten sposób, żaden element nie zostanie wygenerowany w przypadku wyjątek i nie trzeba zrobić dodatkowy błąd obsługi poniżej.

Powiązane problemy