Java 8 Streams Tutorial
By AmarSivas | | Updated : 2021-12-12 | Viewed : 7428 times

In this tutorial, we are going to learn what is the Stream how to use it and how to use Streams in Java 8. Moreover, we will earn the execution mechanism and control flow will be addressed here.
Table of Contents:
Streams in Java 8
The hardware world is advancing with a different number of features. one of the key features is the
It might be confusing Streams with normal I/O input/out streams. But when we look deeply into the streams then it will be clear about the Steams and what does it mean.
Example code snippet for Streams
Array.List<String> monthList =
Arrays.asList("jan", "feb", "mar", "apr", "may");
monthList
.stream()
.filter(s -> s.startsWith(",m"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Notice that result printed on the processed list is displayed in the console. The same logic can be implemented in a normal manner. But what is befitting of using the streams is the next question. we will have a deeper look at them here.
Why Java Streams introduced?
To operate the data in bulk it is required to use collections. These operations are executed in a sequential manner hence time consumption is a bit high. Collections are a bit hassle to use in multithreading as they are not thread-safe. Due to this synchronization concept is implemented in Collection classes, manipulating the collections needs more work than usual.
How java 8 streams work?
Let's start by example to understand how Streams is working in Java 8.
Array.List<String> monthList =
Arrays.asList("jan", "feb", "mar", "apr", "may");
monthList
.stream()
.filter(s->s.endsWith("r"))
.forEach(System.out::println);
The main them of Steams is making tasks into subtasks and executing the tasks in a parallel manner. Means code can be segregated into multiple code segments and once done with the process then all code segments result will be integrated.
Technically Speaking, Streams should use an internal mechanism as fork / joining to operate the data. As you know fork/join made subtasks from the task for processing. Once the process is complete for subtask then it will be consolidated for providing the result back. It is required to understand in detail so we will find that in another article.
Parallel vs Sequential Streams
As you know
Operations in Streams
When operations strike in mind about the Streams then these operations are be considered as
Terminal vs Intermediate
Stream operations examples
forEach()
//display the strings with foreach
Arrays.asList("www", ".", "docsconsole", ".", "com")
.stream()
.forEach(System.out::print);
collect()
In other words, it processes the data to create a resulted container i.e., kind of data structure which can be used to create resulted collections.
Arrays.asList(100, 200,201, 302, 403,505)
.stream().filter(s ->{ return s % 2 == 0;}).collect(Collectors.toList())
.forEach(System.out::println);
Here we are filtering even numbers using a filter and then create the list for getting the resulted values into List finally we are displaying all values for the same.
findfirst()
It finds the first element of the stream if exist the first element.
Arrays.asList(1, 2, 3, 7, 8, 9, 10, 12)
.stream()
.sorted(Comparator.reverseOrder())
.findFirst().ifPresent(System.out::println);
Here we took a integer list as elements for sorting. After sorting all the elements then findFirst() can be used to get the first element.
toArray()
It is another terminal operation where it provides all elements of the stream as an array
//convert the stream as array
Object[] strArray = Arrays.asList("eeeee", "bb", "ccc", "dddd", "a")
.stream().toArray();
Arrays.stream(strArray).forEach(System.out::println);
faltMap()
List colors1 = Stream.of(Arrays.asList("red", "blue","green"),Arrays.asList("yellow", "white","back"))
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println(colors1);
Here result will be printed as a single list whereas if you use a map the result is streams you can find the code snippet below.
List colors = Stream.of(Arrays.asList("red", "blue","green"),Arrays.asList("yellow", "white","back"))
.map(List::stream)
.collect(Collectors.toList());
System.out.println(colors);
peek()
This intermediate operation can be applied to streams.
Stream.of("jan", "feb", "mar", "april", "may","june")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
Notice the result of the above program here
filter()
Arrays.asList(1, 2, 3, 7, 8, 9, 10, 12)
.stream().filter(e -> {return e%2 != 0; })
.forEach(System.out::println);
Here result contains the odd number from the given list.
It is another intermediate operation of streams. It provides another stream based on the condition passed to the filter() method.
map()
Another intermediate method can be used to map creation elements based on a given condition.
Arrays.asList(1,2,3,4,5)
.stream()
.map(s -> s * 5)
.forEach(System.out::println);
Observe the result of the above program it will print the result of 5 times table.
sorted()
Another intermediate operation is used for sorting the elements and will provide the result stream.
//display the alphabets in sorting order
Arrays.asList("eeeee", "bb", "ccc", "dddd", "a")
.stream().sorted()
.forEach(System.out::println);
Here all the elements will be sorted and printed in the console.