Stream Interface forEach method.
Streams, a new feature in Java 8 that deals with pipelining and data
processing operations with fluent API.
What that means is as Collections are data storage mechanisms Streams are
data processing mechanisms. We have covered some ground in Streams like we know
what Streams are? We saw how it allows us to write code declaratively. We do
not need to worry about any kind of loops we just worry of our use-case and write
code as story.
We also saw what is Intermediate operation (operation that returns
Stream<T>) and what is Terminal operation (operation that returns
Non-Stream result).
In previous posts we did data setup and we saw how to filter the Stream
using filter() method. In this post we will talk about forEach method.
What is forEach method?

Yes, those are stairs. We all have seen one. What does that signify? Well,
while climbing stairs what we do? We see if there are more stairs available
then climb stairs or else walk. That is what forEach is all about. If the
element is available, then iterate else stop.
Normally we have enhanced for loops or for each loops as below: Click here
to see the data setup.
final
List<Student> students = StudentDataSet.dataSet();
for (final
Student student : students) {
System.out.println(student);
}
What is really going on? You are iterating(climbing) through the List(ladder)
and printing the elements. Don’t you think this is overkill to print the
elements? Why use for loop? Till now we didn’t had other way the iterate
through the Collection but now we do have a great way called Streams.
Let us perform above task in Java 8.
/**
* Performs an action for each element of
this stream.
* No guarantee on element's order.
*/
students.stream()
.forEach(new
Consumer<Student>() {
@Override
public void
accept(Student student) { System.out.println(student);
}
});
Ok great. What happened?

No, this is not
the final solution. Final solution is very elegant. The motive of Inner class
in forEach method is to understand that a Functional interface is here to help
you.
Below is the code
that displays the forEach method of Stream interface.
students.stream()
.forEach(student
-> System.out.println(student));
Above solution
does not have for loops, no inner class, no mutable data. Isn’t it a beauty?
Now let us look
at the first solution again.
/**
* Performs an action for each element of
this stream.
* No guarantee on element's order.
*/
students.stream()
.forEach(new
Consumer<Student>() {
@Override
public void
accept(Student student) {
System.out.println(student);
}
});
The anonymous
inner class Consumer is a functional interface. Read about Functional
interfaces here.
Read more about Consumer interface here.
Consumer
interface represents an operation that accepts single input argument and returns
no result. Isn’t that what we need? ForEach loop accepts the current element
and process it and does not return anything. This matches our criteria.
·
Now as Consumer interface is Functional interface we can pass
Lambda operator to it. So we can write it like this:
students.stream().forEach((Student student) -> System.out.println(student));
students.stream().forEach((Student student) -> System.out.println(student));
·
But in functional interface we can remove the type(Student)
of parameter as compiler can reference that target type will be Student. If you
are using some method that accepts two different types of parameters, then you
need to explicitly provide the type. We will talk about this later. So we can
again make our code better.
students.stream()
.forEach((student)
-> System.out.println(student));
·
If there is single parameter then we can eliminate the
brackets outside the parameter too.
students.stream()
.forEach(student
-> System.out.println(student));
·
Excellent isn’t it? You can use method reference here too. We
will talk about it later.
students.stream()
.forEach(System.out::println);
Now you compare
the code that we wrote with for-each loop and the one with method reference or
lambda operator.
Awesome isn’t
it. But remember one thing forEach method of Stream interface does not
guarantee the that elements are processed in sequential order.
To summarize use
forEach method in Stream used to do some activity while iterating the data
source in our case the data source is collection.
In next post we
will see allMatch method of Stream interface. It returns true if given
condition is true for all elements in Stream and returns false if atleast once
given condition is false. It accepts Predicate (functional interface) as
argument.
If there is
anything wrong or needs improvement or have any doubts, please post in comments
below. I will reply them. Thanks for reading.
No comments:
Post a Comment