2015-02-19 21 views
19

Giả sử tôi muốn xem một đối tượng có tồn tại trong luồng không và nếu nó không có mặt, hãy ném Ngoại lệ. Một cách tôi có thể làm điều đó sẽ sử dụng phương pháp orElseThrow:Ném ngoại lệ nếu tùy chọn <> hiện diện

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

Điều gì ngược lại? Nếu tôi muốn ném một ngoại lệ nếu có hợp được tìm thấy:

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

Tôi chỉ có thể lưu trữ các Optional, và làm isPresent kiểm tra sau:

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

Có cách nào để đạt được ifPresentThrow loại này của hành vi? Đang cố gắng ném theo cách này là một thực hành xấu?

+3

Điểm của 'orElseThrow' là chuyển đổi giá trị thành không bắt buộc với xử lý lỗi nếu giá trị không tồn tại. Vì tất cả những gì bạn quan tâm là nếu giá trị tồn tại, tại sao không sử dụng phương thức được thiết kế cho mục đích này: 'isPresent'? –

Trả lời

15

Vì bạn chỉ quan tâm đến nếu một trận đấu đã được tìm thấy, không phải những gì đã thực sự tìm thấy, bạn có thể sử dụng anyMatch cho điều này, và bạn không cần sử dụng Optional ở tất cả:

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

hoặc '.anyMatch (" two ":: equals)' – Misha

+5

@Misha: đây là một trong những trường hợp hiếm hoi mà biểu thức lambda hiệu quả hơn vì nó không chụp bất kỳ giá trị nào (như '" hai "' là hằng số biên dịch). Ngược lại, tham chiếu phương thức sẽ luôn ghi lại cá thể mà phương thức sẽ được gọi. – Holger

+0

Tôi biết @Holger là đúng, nhưng tôi phải thừa nhận rằng @ Misha's '" two ":: equals' là một cú pháp rất hay. Thật khó để nói không với điều đó để đạt được một vài nonosecs của hiệu suất :-) –

18

Bạn có thể sử dụng ifPresent() gọi để ném một ngoại lệ nếu bộ lọc của bạn tìm thấy bất cứ điều gì:

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

Nó không thể được ném vào phương pháp ifPresent. – jeon

+1

Có thể thực hiện như sau. 'Optional.of (1) .ifPresent (s -> {ném new RuntimeException (" oh look a exception ");});' – beresfordt

+0

Chỉ RuntimeException có thể được ném theo cách đó – zmark

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