Java 8 has introduced a new concept called Stream. These are a group of computations specified as a sequence of steps. Although, the name sounds similar to Java IO API classes like InputStream/OutputStream, this has nothing to do with them. This is a famous feature in functional programming. Java 8 has adopted this feature of functional programming and named it as Stream.
Streams can work on various input sources like Arrays, Collections etc. A Stream can also be created using a list of objects using Stream interface. This supports various data types. We can also create primitive data type streams using interfaces IntStream, LongStream and DoubleStream.
The below example illustrates some of the possible ways a Stream can be created and manipulated:
loading...
Output:
BLUE BIRD
RED BIRD
YELLOW BIRD
Red Bird
Yellow Bird
Blue Bird
Blue Bird
Red Bird
Yellow Bird
Yellow Bird
Blue Bird
6
6000000
7.8
RED BIRD
YELLOW BIRD
Red Bird
Yellow Bird
Blue Bird
Blue Bird
Red Bird
Yellow Bird
Yellow Bird
Blue Bird
6
6000000
7.8
In the example above, Observe how we can apply all functions on the streams using simple commands.
Remember!
One important thing to note in the example is the usage of forEach. forEach is not a method of List but still we can use it as if its a part of the List interface. How is this possible ? This is possible because forEach is a default method in List. This is the realtime usage of a default method in Collections API.
If you open up the source file of Iterable interface you will see forEach method declared as default.
loading...
Note that List interface extends Collection interface and Collectioninterface extends Iterable. This is how forEach works in List.
Let us see some advanced stream functions. Most important of them all are below :
Collect - This is used to collect the results into a collection i.e, List, Set or a Map.
FlatMap - A map() function is used to apply a function say toUpperCase and transform the existing stream however, it does not return the output as multiple streams. The flatMap() is used to do exactly this, i.e, it returns multiple streams from a single stream.
Reduce - Reduce as the name suggests combines multiple elements and reduces it to a single result.
ParallelStream - The parallelStream() method is used to run the steps/streams in parallel. Imagine this as if you are running the methods in multithreaded environment with a pool of threads.
Remember!
By default the number of threads in this pool is system dependent. To use a custom pool size, use the below JVM argument when running the below example,
-Djava.util.concurrent.ForkJoinPool.common.parallelism=5
The below example illustrates all of the above functions with examples for each type:
loading...
Output:
Actual List : [Red Bird, Yellow Bird, Blue Bird, Yellow Bird]
Collect example using toSet : [RED BIRD, YELLOW BIRD, BLUE BIRD]
Collect example using toList : [Blue Bird, Black Bird]
Collect example using toMap : {1=BLUE, 2=RED, 3=BLACK}
Using flatMap() : 1
Using flatMap() : 2
Using flatMap() : 1
Using flatMap() : 2
Using flatMap() : 1
Using flatMap() : 2
reduce() using Objects : BLACK
reduce() using primitivies : 17
Parallel Streams default pool size : 3
Thread Name in filter : main
Thread Name in map : main
RED BIRD7
Thread Name in filter : main
Thread Name in map : main
RED BIRD6
Thread Name in filter : main
Thread Name in map : main
RED BIRD9
Thread Name in filter : main
Thread Name in map : main
RED BIRD10
Thread Name in filter : main
Thread Name in map : main
RED BIRD8
Thread Name in filter : ForkJoinPool.commonPool-worker-1
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD2
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD1
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD5
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD4
Thread Name in map : ForkJoinPool.commonPool-worker-1
RED BIRD3
Collect example using toSet : [RED BIRD, YELLOW BIRD, BLUE BIRD]
Collect example using toList : [Blue Bird, Black Bird]
Collect example using toMap : {1=BLUE, 2=RED, 3=BLACK}
Using flatMap() : 1
Using flatMap() : 2
Using flatMap() : 1
Using flatMap() : 2
Using flatMap() : 1
Using flatMap() : 2
reduce() using Objects : BLACK
reduce() using primitivies : 17
Parallel Streams default pool size : 3
Thread Name in filter : main
Thread Name in map : main
RED BIRD7
Thread Name in filter : main
Thread Name in map : main
RED BIRD6
Thread Name in filter : main
Thread Name in map : main
RED BIRD9
Thread Name in filter : main
Thread Name in map : main
RED BIRD10
Thread Name in filter : main
Thread Name in map : main
RED BIRD8
Thread Name in filter : ForkJoinPool.commonPool-worker-1
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD2
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD1
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD5
Thread Name in filter : ForkJoinPool.commonPool-worker-2
Thread Name in map : ForkJoinPool.commonPool-worker-2
RED BIRD4
Thread Name in map : ForkJoinPool.commonPool-worker-1
RED BIRD3
As you can see from the output that in case of parallel streams, each of the steps are executed by either of the three threads namely ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2 and main thread. Yes, even the main thread is used as a thread inside the pool. All the other examples are self-explanatory from their output.
Stream in Java 8 is a vast topic and the above quick examples should make give you a quick overview of the new functionality.
Thats all folks !! Happy coding. If you feel this helped you, keep supporting us by or or below or on the articles on social media.