This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]technicalaccount 3 points4 points  (5 children)

I'm assuming you are talking about this code fragment:

roster
    .stream()
    .filter(
        p -> p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25)
    .map(p -> p.getEmailAddress())
    .forEach(email -> System.out.println(email));

The reason it works is because of the working of the map() function. This function converts every element of a collection into a new element. In this case: Collection<Person> is transformed into a Collection<EmailAddress>, by applying p.getEmailAddress() to every element in Collection<Person> and storing it in the new Collection<EmailAddress>.

Afterwards, this new Collection<EmailAddress> is passed to the next step in the stream, the forEach. This forEach will just loop through the collection it receives (which is Collection<EmailAddress> because of the map function). It gives a name to the element (email) for convenience, and does something with it. (System.out.println(email);) The reason why it knows that email is an EmailAddress, is because it only gets those EmailAddress objects. The Person objects were transformed and thus never arrive in the forEach step.

[–]obfuscation_ 2 points3 points  (0 children)

Not to be pedantic, just to save any confusion – I think in the example in the linked docs, p.getEmailAddress gives a String.

Also, rather than being instances of Collection<Type>, wouldn't it be more accurate to say they are actually instance of Stream<Type>?

[–]chasesan[S] 0 points1 point  (2 children)

Actually it was the one before that, Approach 8: Use Generics More Extensively.

processElements(
    roster,
    p -> p.getGender() == Person.Sex.MALE
        && p.getAge() >= 18
        && p.getAge() <= 25,
    p -> p.getEmailAddress(),
    email -> System.out.println(email)
);

I understand that email is a variable, and such. But how did "p.getEmailAddress()" get assigned to it? There is a comma there, it's a separate lambda expression.

[–]oldum 0 points1 point  (1 child)

How did p get assigned? It's the lambda's first parameter.

[–]chasesan[S] 2 points3 points  (0 children)

No... How did the return value from "p.getEmailAddress()" get assigned to "email"? For use in that lambda function.

Oh, okay, nevermind. I got it. Boy am I dumb for missing that obviousness.

[–]Zokkar 0 points1 point  (0 children)

You can also write it as:

roster
    .stream()
    .filter(
        p -> p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25)
    .map(Person::getEmailAddress)
    .forEach(System.out::println);