4

I am new to java and to stream so my question is why does this work:

This method is in my Tree class:

public Stream<Tree> flattened() {
    return Stream.concat(
            Stream.of(this),
            children.stream().flatMap(Tree::flattened));
}

flatMap wants a function with t as param and flattened method doesnt have input parameters at all

whats happening here?

3
  • 2
    @Jeremy you are looking at it Commented Mar 7, 2017 at 22:41
  • 2
    @Jeremy That is the source for Tree::flattened. Commented Mar 7, 2017 at 22:41
  • 1
    the source is the same method Commented Mar 7, 2017 at 22:41

1 Answer 1

8

There is indeed a hidden parameter in your function call. Because flattened is a non-static method, there is an implicit parameter in your function, which is known as this.

Basically, you are calling flattened on each object in your stream, with the said element being your parameter.

EDIT (for clarification): Tree::flattened can mean one of two things. It could mean:

tree -> Tree.flattened(tree) //flattened is a static method, which yours is not

or it could also mean:

tree -> tree.flattened() //flattened is an instance method, as in your case

further to that, it could also mean:

tree -> this.flattened(tree) //also doesn't apply to your case

From the JLS:

If the compile-time declaration is an instance method, then the target reference is the first formal parameter of the invocation method. Otherwise, there is no target reference

Sign up to request clarification or add additional context in comments.

12 Comments

This is a bit of an oversimplification, but for these purposes, public Stream<Tree> flattened() is basically the same thing as public static Stream<Tree> flattened(Tree this).
In fact, I see you are already using it in your method: Stream.of(this).
@JoeC your answer is kind of correct, but the way you phrase it and your last comment make me wonder whether this is the best way to explain it.
@Joey there's no "hidden implementation". It is just syntactic sugar. The compiler is able to infer the type of the lambda you're writing because Tree::flattened contains all the context you need to build a lambda that takes a Tree and returns a Stream<Tree>. If your method was taking even just one parameter you would not be able to write this
I would put it this way: Tree::flattened is equivalent to tree -> tree.flattened() when flattened() is an instance method.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.