2015-09-30 8 views
6

:Java 8'deki zincirleme bir deyimde null olup olmadığını veya özel durumları kontrol etmenin doğru yolu nedir? Bu kod için Örneğin

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

Bu kod şimdi iyi çalışır. Ancak, akışta boş bir liste olduğunu varsayalım ve akış için tonlarca işlem yaptık. NullPointer istisnaları ve benzeri olabilir. Bu tür bir deyim için denemeyi de zor buluyorum. Bunun için kural dışı durumun üstesinden gelmenin doğru yolu nedir?

+3

Ne? Boşsa, hiçbir şey uygulanmayacaktır. Yakalamayı dene? Nerede? Niye ya? –

+1

"akışta boş liste" ne demek istiyorsun? Akışınız Dize değil, Liste'dir. "Akıştaki boş dize" mi demek istediniz? – Bohemian

cevap

7

Boşlukları kontrol etmeniz gerekmez. Eğer tüm işlemler atlanacak boş akışı varsa:

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

durum işleme eşleştiricisindeki mümkündür:

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

özel durumlar göz ardı etmek istiyorsanız, o zaman Optional s eşlemek öneririm.

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

da java 8 akışları ile birlikte daha ayrıntılı bir tartışma hakkında Class.forName için How can I throw CHECKED exceptions from inside Java 8 streams? bir göz atınız.

+2

Her ikisi de = = '. 'İsteğe bağlı', 'Optional.isPresent' ile filtrelemeyi ve 'İsteğe bağlı' filtrelemeyi eşleştiren üç adımın gereksiz yere karmaşık olduğunu unutmayın. Tek bir 'flatMap' işlemi yapabilir. – Holger

4

Sorunuz biraz garip. Class.forName tarafından bildirilen kontrol edilmiş istisnayı ele almadığınız için derleme zamanı hataları oluştururken “Bu kod şimdi iyi çalışıyor” iddiasındasınız. Ayrıca boş listeler hakkında konuşuyorsunuz, ancak kodunuzda hiçbir liste yer almıyor. Aynı şey, herhangi bir yerde null kodunuzu üretmediğinden NullPointerException referansınız için de geçerlidir.

Muhtemelen, ClassNotFoundException'u yakalayan bir koddan bahsediyorsunuz ve null'u döndürerek işliyorsunuz. Bunu asla yapmamalısın. Eğer hatalarını filtrelemek istiyorsanız, bu şekilde yapabilirsiniz:

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

Bu şekilde, hiçbir eleman bir istisna durumunda oluşturulacak ve mansap işleme ek hata yapmaya gerek yok.

İlgili konular