2016-08-15 3 views
2

Я пытаюсь вернуть список completable будущего что-то вроде, как показано ниже,Возвращение Списка completable будущего с Факультативным объектом

List<CompletableFuture<Optional<ModelObject>>> collect = 
      listOfModel. 
      stream(). 
      map(modelObject -> CompletableFuture.supplyAsync(
        ()-> { 
         try { 
           return callMethodWithReturnTypeOfOptional<ModelObject>(modelObject); 
         } catch(Exception e) { 
          LOGGER.error("Something bad happened"); 
          return null; // what should be returned here? 
          // return Optional.<ModelObject>empty(); 
         } 
        } 
      , executor)). 
      collect(Collectors.<CompletableFuture<Optional<ModelObject>>>toList()); 

Есть ли лучший способ обработки исключений здесь? Возврат Optional.empty(); является хорошей практикой? Спасибо за помощь!

ответ

0

Это не понятно, почему callMethodWithReturnTypeOfOptional возвращает Optionalи бросают исключения, но если предположить, что возвращение пустого необязательного и бросать исключение имеют различные значения, мы не должны отбросить эту информацию. Таким образом, ответ заключается в том, что вы не должны полностью исключать исключение, так что CompletableFuture может сообщить об этом. Если рассматриваемый метод объявляет проверил исключения, просто поймать, обертывание и Rethrow их:

List<CompletableFuture<Optional<ModelObject>>> collect = 
    listOfModel.stream() 
    .map(modelObject -> CompletableFuture.supplyAsync(
     ()-> { 
      try { 
       return callMethodWithReturnTypeOfOptional(modelObject); 
      } catch(Exception e) { 
       throw new CompletionException(e); 
      } 
     }, 
     executor)) 
    .collect(Collectors.toList()); 

Использование CompletionException, как исключение обертка имеет то преимущество, что CompletableFuture не будет обмотать исключение в другом CompletionException, поэтому этот тип исключения является естественным выбором в рамках действия, переданного в CompletableFuture.

Обратите внимание, что вы можете избежать захвата лямбда-выражения естественным образом здесь:

List<CompletableFuture<Optional<ModelObject>>> collect = 
    listOfModel.stream() 
    .map(CompletableFuture::completedFuture) 
    .map(f -> f.thenApplyAsync(
     modelObject -> { 
      try { 
       return callMethodWithReturnTypeOfOptional(modelObject); 
      } catch(Exception e) { 
       throw new CompletionException(e); 
      } 
     }, 
     executor)) 
    .collect(Collectors.toList()); 

Если метод не бросает проверил исключения, этот код упрощает для

List<CompletableFuture<Optional<ModelObject>>> collect = 
    listOfModel.stream() 
    .map(CompletableFuture::completedFuture) 
    .map(f -> f.thenApplyAsync(Owner::callMethodWithReturnTypeOfOptional, executor)) 
    .collect(Collectors.toList()); 
+0

Спасибо за Ваш комментарий , Вы правы, нет смысла иметь этот избыточный блок исключений и спасибо за этот упрощенный код! – Coder

Смежные вопросы