2016-02-11 11 views
14

Tôi đã ngạc nhiên bởi phương thức Optional.ofNullable. Một ngày nào đó tôi đã viết một chức năng mà phải trả lại một Tùy chọn:Optional.ofNullable and method chaining

private Optional<Integer> extractFirstValueFrom(InsightsResponse insight) { 
    return Optional.ofNullable(insight.getValues().get(0).getValue()); 
} 

tôi lầm tưởng rằng Optional.ofNullable sẽ ngăn chặn bất kỳ NullPointerExceptions bên bày tỏ lập luận.

Bây giờ tôi nghĩ rằng tôi biết rằng đó là ý tưởng rất ngu ngốc. Java phải giải quyết các đối số đầu tiên để chuyển nó tới yêu cầu Optional.ofNullable.

Nhưng tôi có một câu hỏi. Có cách nào tốt đẹp và tốt để hoàn thành mục tiêu của tôi không? Tôi muốn lấy từ biểu thức insight.getValues().get(0).getValue() một số giá trị Integer hoặc null. Null có thể là một trong các biểu thức: insight.getValues() hoặc insight.getValues().get(0).

Tôi biết rằng tôi chỉ có thể đặt điều này trong khối try/catch nhưng tôi tự hỏi nếu có giải pháp thanh lịch hơn.

+0

Trong trường hợp của bạn, 'thông tin chi tiết' là rỗng. Tốt hơn hết là không bao giờ chuyển null vào phương thức thay vì kiểm tra các phương thức bên trong rỗng. –

Trả lời

20

Nếu bạn không có ý tưởng gì có thể được null, hoặc muốn kiểm tra tất cả mọi thứ cho null, cách duy nhất là cuộc gọi chuỗi Optional.map:

Nếu một giá trị hiện tại, áp dụng các chức năng lập bản đồ cung cấp cho nó, và nếu kết quả là không null, trả về một tùy chọn mô tả kết quả. Nếu không thì trả về một tùy chọn rỗng.

Như vậy, nếu người lập bản đồ trả lại null, số trống Optional sẽ được trả lại, cho phép thực hiện cuộc gọi.

Optional.ofNullable(insight) 
     .map(i -> i.getValues()) 
     .map(values -> values.get(0)) 
     .map(v -> v.getValue()) 
     .orElse(0); 

Cuộc gọi cuối cùng để orElse(0) phép để trả lại giá trị mặc định 0 nếu có mapper trở null.

2

smth như thế này nên làm việc

Optional.ofNullable(insight.getValues()).map(vals -> vals.get(0)).map(v -> v.getValue()) 

tốt, theo mẫu mã nhất định, như #extractFirstValueFrom không chứa không @Nullable cũng không kiểm tra cho null như ổi của checkNotNull(), chúng ta hãy giả sử rằng insight luôn là something. do đó, gói Optional.ofNullable(insight.getValues()) vào Option sẽ không kết quả với NPE. sau đó gọi chuỗi các biến đổi được tạo thành (mỗi kết quả với Optional) dẫn đến kết quả Optional<Integer> có thể là Some hoặc None.