Streams are an update to the Java API starting from Java 8.
A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result in a declarative way
Short definition: a sequence of elements from a source that supports data-processing operations
Sequence of elements: just like a collection which is a sequence of data structures (mostly for storing and accessing elements), a stream is a sequence of computations (like filter, sorted, map)
Source: stream consumes a data-providing source like a collection
Data-processing operations: stream provides data-processing operations like filter, sorted, map which can be ran either sequentially or in parallel
+ Pipelining: many stream operations return stream itself, which allows the operations to be pipelined
+ Internal iteration: the iterations are done behind the scenes unlike collections
Instead of doing below before (Java 7)
List<Dish> lowCaloricDishes = new ArrayList<>();
for (Dish dish: menu) {
if (dish.getCalories() < 400) {
lowCaloricDishes.add(dish);
}
}
The code is written in a declarative way - Instead of specifying how to implement what we want using control blocks (for, if, ...), we specify what we want to implement (filter with low calories)
We can easily implement and execute the stream code in parallel with parallelStream
Streams vs. Collections
Streams can only be traversed once (Note that in pipeline, each stream operation returns another stream)
List<String> title = Arrays.asList("Modern", "Java", "In", "Action");
Stream<String> s = title.stream();
s.forEach(System.out:: println);
s.forEach(System.out:: println); // java.lang.IllegalStateException!
Stream has internal iteration while Collection has external iteration
In a collection, you use control blocks (for-each loop, etc) or Iterators
(Modern Java In Action)
Stream Operations
Stream can be summarized into 3 steps: Data Source > Intermediate Operations > Terminal Operation
Intermediate Operations
Operations like filter, map, and limit, which are connected together to form a pipeline
These operations return another stream as the return type, so that the operations can be connected to form a query
Terminal Operations
Operations like count and collect, which produce a result (Integer, List, void, etc) from a stream pipeline