Java 8 Необязательно <List>возвращает True Почему? - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть контроллер REST

@GetMapping("/getByClientId/{clientId}")
 public ResponseEntity<Optional<List<EquityFeeds>>> getByClientId(@PathVariable("clientId") final String clientId) {

 Optional<List<EquityFeeds>> cId = Optional.ofNullable(equityFeedsService.findByClientId(clientId));

  System.out.println("Client Id: "+cId);

        if(cId.isPresent()) {
           return ResponseEntity.ok(cId);
        } else {
           cId.orElseThrow(() -> new ClientIdNotFoundException(clientId));
        }
        return ResponseEntity.ok(cId);
     }

Код класса обслуживания:

public List<EquityFeeds> findByClientId(String clientId) {

        List<EquityFeeds> cId = equityFeedsRedisRepositoryImpl.findByClientId(clientId);
        System.out.println("In EquityFeedService "+cId);
        return cId;
    }

Вкл. Код (REDIS):

public List<EquityFeeds> findByClientId(String clientId) {
      return (List<EquityFeeds>) listOperations.range(clientId, 0, -1);
}

Проблема: 1) Когда getClientId вызывается с использованием контроллера REST, а clientId отсутствует в кэше REDIS, тогда:

Service class Code returns: In EquityFeedService []

The REST Controller returns: Client Id: Optional[[]] 

В REST Controller код идет внутри if l oop и ничего не отображает на экране, так как список пуст, т.е.

if(cId.isPresent()) {
           return ResponseEntity.ok(cId);
 }

Почему? Почему cId.isPresent () возвращает true, а код идет внутри if l oop. В идеале код должен go внутри else l oop и выдавать исключение, так как список пуст. Это происходит только в случае с List, так как мой другой метод с возвращаемым типом POJO не имеет этой проблемы.

Пожалуйста, помогите мне понять это поведение и что нужно сделать, чтобы это исправить.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

cId.isPresent() возврат true, поскольку List<EquityFeeds> не равно нулю, это пустой список

if(!cId.get().isEmpty()) {
   return ResponseEntity.ok(cId);
} else {
   throw new ClientIdNotFoundException(clientId);
}
0 голосов
/ 10 апреля 2020

Причина, по которой Optional.isPresent возвращает true, заключается в том, что существует фактическое значение - пустое List. Optional проверяет, является ли значение, которое он содержит, null или нет, больше ничего. isPresent проверяет, присутствует ли значение внутри Optional, а не внутри самого List.

Таким образом, вы должны трактовать Optional немного по-другому. Более того, не используйте Optional как замену конструктам if-else.

Вот способ go:

return cId.filter(Predicate.not(List::Empty))            // if the list is not empty
          .map(ResponseEntity::ok)                       // create a response
          .orElseThrow(() ->                             // or else throw an exception
               new ClientIdNotFoundException(clientId)); 

Кстати, вы не хотите возвращать Optional, завернутый в ResponseEntity. Разверните его и верните List сам. Если он пуст или null уже обработан, и сначала будет выдано исключение.

return cId.filter(Predicate.not(List::Empty))            
          .map(Optional::get)                            // exctract from the Optional
          .map(ResponseEntity::ok)
          .orElseThrow(() -> new ClientIdNotFoundException(clientId)); 
...