2015-09-30 13 views
6

Ví dụ về mã này:Cách nào đúng để kiểm tra null hoặc kiểm tra ngoại lệ trong câu lệnh xích trong Java 8?

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

Mã này hiện đang chạy tốt. nhưng, giả sử chúng tôi có một danh sách trống trong luồng và chúng tôi có rất nhiều hoạt động đối với luồng. Nó có thể nhận được ngoại lệ NullPointer và vv. Tôi tìm thấy nó cũng khó để cố gắng nắm bắt cho loại tuyên bố. Cách thích hợp để xử lý ngoại lệ cho điều này là gì?

+3

Cái gì? Nếu nó trống, không có gì sẽ được áp dụng. Cố gắng bắt? Ở đâu? Tại sao? –

+1

ý của bạn là "danh sách trống trong luồng"? Luồng của bạn là Chuỗi, không phải Danh sách. Ý của bạn là "chuỗi rỗng trong luồng"? – Bohemian

Trả lời

7

Bạn không cần phải kiểm tra các giá trị rỗng. Nếu bạn có một dòng sản phẩm nào mọi hoạt động sẽ bị bỏ qua:

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

xử lý ngoại lệ là có thể trong mapper:

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

Nếu bạn muốn ngoại lệ đối với bị bỏ qua, sau đó tôi đề nghị để ánh xạ 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()); 

Hãy cũng có một cái nhìn tại How can I throw CHECKED exceptions from inside Java 8 streams? cho một cuộc thảo luận chi tiết hơn về Class.forName kết hợp với java 8 suối.

+2

Không phải là '=>'. Lưu ý rằng ba bước, ánh xạ tới 'Optional', lọc qua' Optional.isPresent', và unwrapping 'Optional' là phức tạp không cần thiết. Một 'bản đồ phẳng 'có thể thực hiện thao tác. – Holger

4

Câu hỏi của bạn hơi lạ. Bạn đang tuyên bố "Mã này chạy tốt ngay bây giờ" trong khi nó sẽ tạo ra các lỗi biên dịch thời gian khi bạn không xử lý ngoại lệ đã kiểm tra được khai báo bởi Class.forName. Hơn nữa bạn đang nói về các danh sách trống, nhưng trong mã của bạn, không có danh sách nào có liên quan. Điều tương tự cũng áp dụng cho việc bạn tham chiếu đến NullPointerException vì mã của bạn không sản xuất null ở bất kỳ nơi nào.

Có thể, bạn đang nói về mã bắt giữ ClassNotFoundException và xử lý mã đó bằng cách trả lại null. Bạn không bao giờ nên làm điều này. Nếu bạn muốn lọc ra các lỗi, bạn có thể thực hiện theo cách này:

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

Bằng cách này, không có yếu tố nào được tạo trong trường hợp ngoại lệ và bạn không phải thực hiện thêm lỗi khi xử lý xuôi dòng.

Các vấn đề liên quan