Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if Collection is not empty using java Stream

I am new to Java 8. I am not able to understand what is wrong in the following piece of code. The idea is to sent Collection<User> if its not empty. But if the collection is empty than sent HttpStatus.NOT_FOUND Entity response.

@RequestMapping(value = "/find/pks", 
                method = RequestMethod.GET, 
                produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<User>> getUsers(@RequestBody final Collection<String> pks)
{
    return StreamSupport.stream(userRepository.findAll(pks).spliterator(), false)
         .map(list -> new ResponseEntity<>(list , HttpStatus.OK))
         .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}

Eclipse shows me error in the following point .orElse

The method orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)) is undefined for the type Stream<ResponseEntity<User>>

My base interface method looks like following

Iterable<T> findAll(Iterable<PK> pks);
like image 659
Saurabh Kumar Avatar asked Jun 03 '15 22:06

Saurabh Kumar


3 Answers

You are mixing two things up. The first task is to convert the Iterable to a Collection which you can indeed solve using the Stream API:

Collection<User> list=
    StreamSupport.stream(userRepository.findAll(pks).spliterator(), false)
   .collect(Collectors.toList());

Note that this stream is a stream of Users, not a stream of lists. Therefore you can’t map a list to something else with this stream. The map operation will map each element of the stream to a new element.

Then you can use this list to create the ResponseEntity

return list.isEmpty()? new ResponseEntity<>(HttpStatus.NOT_FOUND):
                       new ResponseEntity<>(list, HttpStatus.OK);

You can combine these steps by creating a Collector performing this steps though this does not provide any advantage, it’s only a matter of style:

ResponseEntity<User> responseEntity=
    StreamSupport.stream(userRepository.findAll(pks).spliterator(), false)
   .collect(Collectors.collectingAndThen(Collectors.toList(),
      list -> list.isEmpty()? new ResponseEntity<>(HttpStatus.NOT_FOUND):
                              new ResponseEntity<>(list, HttpStatus.OK) ));
like image 167
Holger Avatar answered Oct 21 '22 17:10

Holger


It's not necessary, and often a mistake, to cram everything into one line. In this case, you can't - there's no such API for your intention.

Keep it simple:

Collection<User> list = <your stream code that gets a list>;
if (list.isEmpty())
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
return new ResponseEntity<>(list, HttpStatus.OK);

but if you absolutely must:

return <your code>.map(list -> new ResponseEntity<>(list, list.isEmpty() ? HttpStatus.NOT_FOUND : HttpStatus.OK));
like image 44
Bohemian Avatar answered Oct 21 '22 15:10

Bohemian


That depends on your terminal operation of the stream, remember that a stream can only be consumed once.

  • Is it a grouping by/statistics operation? Then you'll get a 0 count or an empty map of groups.
  • If it collects into a list then it's an empty list.
  • If it's one of the methods that returns an Optional (such as findAny) then you can use the optional's null-checking methods.
like image 41
the8472 Avatar answered Oct 21 '22 17:10

the8472