- A Stream is a pipeline of functions that can be evaluated
- Streams can transform data
- A Stream is not a data structure
- Streams cannot mutate data
We stated that a stream is a pipeline of functions, or operations. These operations can either be classed as an intermediate operation or a terminal operation. The difference between the two is in the output which the operation creates. If an operation outputs another stream, to which you could apply a further operation, we call it an intermediate operation. However, if the operation outputs a concrete type or produces a side effect, it is a terminal type. A subsequent stream operation cannot follow a terminal operation, obviously, as a stream is not returned by the terminal operation!
Intermediate operations
An intermediate operation is always lazily executed. That is to say they are not run until the point a terminal operation is reached. We’ll look in more depth at a few of the most popular intermediate operations used in a stream.- filter – the filter operation returns a stream of elements that satisfy the predicate passed in as a parameter to the operation. The elements themselves before and after the filter will have the same type, however the number of elements will likely change.
- map – the map operation returns a stream of elements after they have been processed by the function passed in as a parameter. The elements before and after the mapping may have a different type, but there will be the same total number of elements.
- distinct – the distinct operation is a special case of the filter operation. Distinct returns a stream of elements such that each element is unique in the stream, based on the equals method of the elements.
| Function | Preserves count | Preserves type | Preserves order |
|---|---|---|---|
| map | ✅ | ❌ | ✅ |
| filter | ❌ | ✅ | ✅ |
| distinct | ❌ | ✅ | ✅ |
| sorted | ✅ | ✅ | ❌ |
| peek | ✅ | ✅ | ✅ |
Terminal operations
A terminal operation is always eagerly executed. This operation will kick off the execution of all previous lazy operations present in the stream. Terminal operations either return concrete types or produce a side effect. For instance, a reduce operation which calls the Integer::sum operation would produce an Optional, which is a concrete type. Alternatively, the forEach operation does not return a concrete type, but you are able to add a side effect such as print out each element. The collect terminal operation is a special type of reduce which takes all the elements from the stream and can produce a Set, Map or List. Here’s a tabulated summary.| Function | Output | When to use |
|---|---|---|
| reduce | concrete type | to cumulate elements |
| collect | list, map or set | to group elements |
| forEach | side effect | to perform a side effect on elements |
All Terminal Operations.
0 comments:
Post a Comment