10

The syntax of map method in java 8 is :

<R> Stream<R> map(Function<? super T,? extends R> mapper)

but i can use a lambda expression :

personList.stream().filter(p -> p.getPersonType().equals("student"))
            .map(p -> new Student(p.getId(), p.getName()))
            .collect(Collectors.toList());

How does the argument in map method equates to a Function datatype.Please help me understand this .

Thanks

1
  • You can write like this Function<Person,Person> function = p -> new Student(p.getId(), p.getName()) Commented Jun 13, 2018 at 11:30

5 Answers 5

9

The function Function<? super T,? extends R> mapper of the map method basically represents any function taking one parameter and returning a value so in this specific case the lambda p -> new Student(p.getId(), p.getName()) is a function taking a Person p and returning a Student hence fits into that perfectly.

To look at it another way, the lambda is equivalent to:

.map(new Function<Person, Student>() {
     @Override
      public Student apply(Person p) {
            return new Student(p.getId(), p.getName());
      }
})
Sign up to request clarification or add additional context in comments.

1 Comment

while i got stuck here i found this explaination infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood quite helpfull too.
3

You can write like this Function<Person,Student> function = p -> new Student(p.getId(), p.getName())

so as you see it is represent a function.

personList.stream().filter(p -> p.getPersonType().equals("student"))
        .map(function::apply) // p -> function.apply(p)
        .collect(Collectors.toList());

Comments

2

In the context of your Stream<Person> (assuming personList is a List<Person>), the lambda expression p -> new Student(p.getId(), p.getName()) implements a functional interface that accepts a Person instance (an element of your Stream) and returns a Student instance.

Hence it matches the Function<Person,Student> functional interface, which is the interface required by the map() method.

Comments

1

At runtime, the following lambda expression:

p -> new Student(p.getId(), p.getName())

will be represented by the class that implements Function<T, R> interface.

An instance of this functional interface can be passed as a parameter to Stream.map(...) method:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

In order to get a better understanding of how this works, one could replace a lambda with a good old anonymous class that implements the corresponding interface.

.map(p -> new Student(p.getId(), p.getName())) is equivalent to:

.map(new Function<Person, Student>() {
    @Override
    public Student apply(Person p) {
        return new Student(p.getId(), p.getName());
    }
})

Comments

0

Same as @Ousmane D. but instead of this:

.map(new Function<Person, Student>() {
     @Override
      public Student apply(Person p) {
            return new Student(p.getId(), p.getName());
      }
})

Try this:

Function<Person, Student> f = p -> new Student(p.getId(), p.getName());

and use it inside your stream with .map(f).

Comments

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.