Reputation: 41
I am new to java8. I was trying to understand working of foreach loop in Streams. My code is as follows:-
Stream<String> s = someist.stream();
Consumer<String> consumer = (String s1)->System.out.println(s1);
s.forEach(consumer);
Question is how does foreach loop know to call consumer.accept(T t) when i am just passing the reference of Consumer and not calling consumer.accept(T t) inside it. Although, when we provide some lambda expression for a functional interface we need to call its abstract method, we are just not calling it here. So how does foreach loop comes to know what should it do with the consumer reference provided as a parameter?
Upvotes: 3
Views: 1811
Reputation: 374
This is how Functional Interface
works. They have only one abstract
method. There might be optional default
methods. The behaviour of the abstract
method is passed in form of lambda expression
(passing behaviour as if data). This behaviour is, in turn, the method body for the abstract
method of the Functional Interface
. The default
methods are called using their names.
So when you pass a Functional Interface
as a method parameter to another method, in this case, Consumer<T>
to the forEach()
method of java.util.stream.Stream
interface, its abstract method accept(T t)
is called for each item of the stream.
Put it this way, logically, there's only one method to be invoked if only the Functional Interface
is passed as a parameter.
Upvotes: -1
Reputation: 56433
As the java doc states:
void forEach(Consumer<? super T> action)
Performs an action for each element of this stream.
i.e the behavioural parameter passed to the forEach
method will be called internally for each element of the source.
Upvotes: 1
Reputation: 28279
The concrete implemention of forEach
will call accept
, for example:
public class MyStream implements Stream<String> {
@Override
public void forEach(Consumer<? super String> action) {
while (hasNext()) {
action.accept(next());
}
}
...
}
Upvotes: 2