Je ne sens pas la différence entre les méthodes map()
et mapToObj()
dans les flux Java 8. Dans les deux, nous pouvons créer et renvoyer des objets dans les flux, alors pourquoi ces méthodes existent en deux, pas seulement une.
Pourriez-vous me donner l'explication avec des exemples?
Vous verrez ce motif cool. Les classes Stream
incluent un IntStream
, LongStream
, DoubleStream
etc. C'est ainsi que vous pouvez utiliser des types primitifs dans les opérations de flux. Sinon, vous devez utiliser Stream<Integer>
ou Stream<Double>
, qui encadrera les valeurs.
De même, les méthodes map
font également cela. Dans le Stream<T>
class, il existe des méthodes mapToInt
, mapToDouble
, mais la situation est un peu différente dans les classes IntStream
, DoubleStream
.
Dans IntStream
, la méthode map
prend un IntUnaryOperator
, qui mappe un int à un int. Si vous souhaitez mapper le flux à un Stream<T>
, vous devez utiliser mapToObj
. mapToObj
est un bon nom car il se distingue du map
qui correspond aux ints. Cela signifie que le flux passe d'un IntStream
à un Stream<T>
. La raison pour laquelle mapToObj
est nommée ainsi est la même raison pour laquelle mapToInt
est nommée ainsi - pour signifier une modification du type Stream
/
Les versions primitive
et object
des types de données (c'est-à-dire int et Integer, double et Double, etc.) ne sont pas vraiment compatibles entre elles en Java. Ils sont rendus compatibles grâce à l'étape supplémentaire de auto-boxing/unboxing
. Ainsi, si vous avez un flux d'entiers primitifs et si vous essayez d'utiliser les versions objet de Stream et Function (c'est-à-dire Stream et Function, vous encourrez le coût de la mise en boîte et du déballage des éléments.
Pour éliminer ce problème, le package de fonctions contient primitive specialized versions of streams
aussi bien que functional interfaces
. Par exemple, au lieu d'utiliser Stream<Integer>
, vous devez utiliser IntStream
. Vous pouvez désormais traiter chaque élément du flux à l'aide d'IntFunction. Cela évitera complètement la boxe automatique/unboxing.
Ainsi, chaque fois que vous souhaitez traiter des flux d'éléments primitifs, vous devez utiliser les flux spécialisés primitifs (c'est-à-dire IntStream, LongStream et DoubleStream) et les interfaces fonctionnelles spécialisées primitives (c'est-à-dire IntFunction, IntConsumer, IntSupplier, etc.) pour obtenir de meilleures performances.
Une autre chose à noter est qu'aucune des interfaces fonctionnelles spécialisées primitives (telles que IntFunction, DoubleFunction ou IntConsumer) n'étend les interfaces fonctionnelles non primitives (c'est-à-dire Function, Consumer, etc.).
Java.util.function package
contient les versions int, double et longue (mais pas flottante) de toutes les interfaces fonctionnelles. Par exemple, il existe une IntFunction, une DoubleFunction et une LongFunction, qui sont des versions int, double et longue de Function. Ces fonctions sont utilisées avec des versions spécialisées primitives de flux tels que IntStream, DoubleStream et LongStream.
Prenons quelques exemples:
Stream stream = Stream.of(1, 2, 3); //Will compile fine
IntStream intStream = IntStream.of(4, 5, 6); //Will compile fine
Stream s = IntStream.of(4, 5, 6); //Does not compile
Stream s = IntStream.of(4, 5, 6).mapToObj(e -> e); //mapToObj method is needed
IntStream is = Stream.of(4, 5, 6).mapToInt(e -> e); //mapToInt method is needed
En conclusion, la raison pour laquelle vous pourriez utiliser mapToObj
est la même que vous pourriez utiliser mapToInt
, qui est de changer le type de flux.