Java 8 Streams API tutorial starts off with defining Java 8 Streams, followed by an explanation of the important terms making up the Streams definition. We will then look at Java 8 code examples showing how to exactly use Streams API. By the end of this tutorial you should feel confident of writing your first program utilising Java 8 Streams API.
What are Streams/Defining Streams
A Stream in Java is a sequence of elements supporting parallel and aggregate operations. This sequence of elements are obtained from a source. Further, streams in Java 8 support processing of these elements through operations defined in a declarative way. These operations are linked-up according to the principle of pipelines
Click to Understand the concept of Pipelines in Computing and they access the elements via Internal Iterations.
Conceptual terms making up the Streams definition
Streams definition given above has a lot of terms put together. To understand this definition in its totality we need to understand each of these terms. Lets look at them one-by-one:
- Sequence of elements – A stream provides an interface to a sequenced set of values of a specific type. For e.g.
Stream<Integer>is a stream of type
- Source of stream elements – Streams are defined as originating from a specific source which can be collections, arrays, input-output(I/O) resources etc
- Operations on stream elements – As the stream’s elements are encountered, several pre-defined operations can be declared to act on the stream elements to map, reduce and collect these elements.
- Parallel and aggregate operations – The operations working on these stream of elements can work in parallel on multi-core architectures. Aggregate operations act on elements in the stream in a sequence and end up aggregating data into an end value.
- Pipeline of Operations – Various operations which have been declared to act on a stream work together based on the concept of Pipelines(link to tutorial
Click to Understand the concept of Pipelines in Computing). I.e. output of one stream operation acts as input of the next stream operation.
- Internal iterations– Internal iterations delegate the work of iterating to the Streams library. The programmer just needs to specify in a declarative manner as to which operation has to be applied to the stream of elements.
Streams API usage example
To start with, let us look at a class
Employee.java which has –
- 2 instance attributes –
- Getters and setters for these attributes.
- A constructor with both attributes.
BasicStreams.java, given below, in which I have –
- A static list of employees called
main()method where I have my streams-based filter logic
- I initialise my list of Employees with 5 Employee Objects using the 2-parameter
Employeeconstructor which utilises the
- The program starts with static import of
toList()method. This method is used to get a list from a stream
- In the
stream()is invoked on employeeList. The method
stream()has been newly introduced in Java 8 on the interface Collection which List interface extends. This
stream()method gives an instance
java.util.Streamas the return type
- The stream of employees is then passed(or pipe-lined) to the function
limit()function puts a limit to the maximum number of elements which will be picked from the stream. In the given example I have passed the value 2, hence the current stream is now limited to first 2 elements. Also, note that
limit()is an intermediary operation i.e. the stream processing does not end with
collect()method is then invoked on the stream(which now has only 2 elements).
Collectorof a specific type which in the given example is of type
List(returned by the static
Collectorsclass). To simplify the previous statements,
toList()method to return a list equivalent of the stream pipe-lined into it(named
filteredList). Note that
collect()is a terminal operation i.e. the processing of the stream ends with the
- At the end, I simply use a Java 8 style
forEachloop and a Method Reference
Click to Read Tutorial on Java 8’s Method References to the
System.out.println()method to print all the elements in the resultant
- As expected the 2 employee objects are printed using the overridden
In the above tutorial we saw what Java 8 Streams are, understood the various terms which describe a Stream, and finally saw a basic example of how to start using Streams in your programs using the intermediary & terminal operations.