web-dev-qa-db-fra.com

Java Différence de flux entre map et mapToObj

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?

29
masterofdisaster

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 /

37
Sweeper

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.

16
Alex Mamo