Expression lambda méthode de carte java 8
La syntaxe de la méthode map en java 8 est:
<R> Stream<R> map(Function<? super T,? extends R> mapper)
Mais je peux utiliser une expression lambda:
personList.stream().filter(p -> p.getPersonType().equals("student"))
.map(p -> new Student(p.getId(), p.getName()))
.collect(Collectors.toList());
Comment l'argument de la méthode map équivaut-il à un type de données de fonction.Merci de m'aider à comprendre cela .
Merci
4 answers
La fonction Function<? super T,? extends R> mapper
de la méthode map
représente essentiellement toute fonction prenant un paramètre et renvoyant une valeur, donc dans ce cas spécifique, le lambda p -> new Student(p.getId(), p.getName())
est une fonction prenant un Person
p et renvoyant un Student
s'intègre donc parfaitement dans cela.
Pour le regarder d'une autre manière, le lambda est équivalent à:
.map(new Function<Person, Student>() {
@Override
public Student apply(Person p) {
return new Student(p.getId(), p.getName());
}
})
, Dans le cadre de votre Stream<Person>
(en supposant que personList
est un List<Person>
), l'expression lambda p -> new Student(p.getId(), p.getName())
implémente une interface fonctionnelle qui accepte un Person
exemple (un élément de votre Stream
) et retourne un Student
exemple.
Par conséquent, il correspond à l'interface fonctionnelle Function<Person,Student>
, qui est l'interface requise par la méthode map()
.
Vous pouvez écrire comme ceci Function<Person,Student> function = p -> new Student(p.getId(), p.getName())
Donc, comme vous le voyez, il représente une fonction.
personList.stream().filter(p -> p.getPersonType().equals("student"))
.map(function::apply) // p -> function.apply(p)
.collect(Collectors.toList());
Au moment de l'exécution, l'expression lambda suivante:
p -> new Student(p.getId(), p.getName())
Sera représenté par la classe qui implémente l'interface Function<T, R>
.
Une instance de cette interface fonctionnelle peut être passée en paramètre à la méthode Stream.map(...)
:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Afin de mieux comprendre comment cela fonctionne, on pourrait remplacer un lambda par une bonne vieille classe anonyme qui implémente l'interface correspondante.
.map(p -> new Student(p.getId(), p.getName()))
est équivalent à:
.map(new Function<Person, Student>() {
@Override
public Student apply(Person p) {
return new Student(p.getId(), p.getName());
}
})