Streams

A stream represents a sequence of elements and can perform a series of operations on them

strings.stream()
.filter(s -> !s.equals(""))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);

Operations on streams can be intermediate or final.

  • Intermediate: they return a stream to be able process them into chain.
  • Finals: they return either void or a result that does not it is a stream.

These operations must work without interference and stateless.

  • Intermediate operations will not be executed if there is no final operation.
  • The chain operation is followed vertically.
  • Streams are closed as soon as we execute a terminal operation.
  • Parallel streams can improve when we consider a large data size.
  • They are implemented with Fork/Join pool, with all the advantages and disadvantages that this entails.

From the viewpoint of parallelism, an important benefit of using Java streams when possible is that the pipeline can be made to execute in parallel by designating the source to be a parallel stream, by simply replacing .stream() by .parallelStream() or Stream.of(xxx).parallel. This form of functional parallelism is a major convenience for the programmer, since they do not need to worry about explicitly allocating intermediate collections, or about ensuring that parallel accesses to data collections are properly synchronized.