Suvigya Gupta
Suvigya Gupta

Reputation: 41

java8 + internal working of for each loop

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

Answers (3)

mark42inbound
mark42inbound

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

Ousmane D.
Ousmane D.

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

xingbin
xingbin

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

Related Questions