map 和 mapToObj 之间的 Java Stream 区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47807758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Stream difference between map and mapToObj
提问by masterofdisaster
I don't feel the difference between map()
and mapToObj()
methods in Java 8 Streams. In both we can create and return objects to the streams, so why these methods exist as two, not only one.
我感觉不到Java 8 Streams 中的map()
和mapToObj()
方法之间的区别。在这两者中,我们都可以创建对象并将对象返回给流,那么为什么这些方法以两种形式存在,而不仅仅是一种。
Could you give me the explanation with examples?
你能用例子给我解释一下吗?
回答by Sweeper
You will see this cool pattern. The Stream
classes includes a IntStream
, LongStream
, DoubleStream
etc. This is so that you can use primitive types in stream operations. Because otherwise you have to use Stream<Integer>
or Stream<Double>
, which will box the values.
你会看到这个很酷的图案。该Stream
课程包括IntStream
,LongStream
,DoubleStream
等,这是为了让您可以在流操作使用原始的类型。因为否则你必须使用Stream<Integer>
or Stream<Double>
,它会将值装箱。
Similarly, the map
methods also do this. In the Stream<T>
class, there are mapToInt
, mapToDouble
methods, but the situation is a little bit different in the IntStream
, DoubleStream
classes.
同样,这些map
方法也这样做。在Stream<T>
类中,有mapToInt
,mapToDouble
方法,但在IntStream
,DoubleStream
类中情况略有不同。
In IntStream
, the map
method takes an IntUnaryOperator
, which maps an int to an int. If you want to map the stream to a Stream<T>
, you have to use mapToObj
. mapToObj
is a good name because it distinguishes from the map
that maps to ints. It signifies that the stream changes from a IntStream
to a Stream<T>
. The reason why mapToObj
is named like so is the same reason why mapToInt
is named like so - to signify a change in the Stream
type/
在 中IntStream
,该map
方法采用一个IntUnaryOperator
,它将一个 int 映射到一个 int。如果要将流映射到Stream<T>
,则必须使用mapToObj
. mapToObj
是一个好名字,因为它区别于map
映射到整数的那个。它表示流从 aIntStream
变为 a Stream<T>
。mapToObj
如此命名的原因与如此命名的原因相同mapToInt
- 表示Stream
类型的变化/
回答by Alex Mamo
The primitive and object versions of data types (i.e. int and Integer, double and Double, etc.) are not really compatible with each other in Java. They are made compatible through the extra step of auto-boxing/unboxing. Thus, if you have a stream of primitive ints and if you try to use the object versions of Stream and Function (i.e. Stream and Function), you will incur the cost of boxing and unboxing the elements.
To eliminate this problem, the function package contains primitive specialized versions of streams as well as functional interfaces. For example, instead of using Stream<Integer>
, you should use IntStream
. You can now process each element of the stream using IntFunction
. This will avoid auto-boxing/unboxing altogether.
数据类型的原始版本和对象版本(即 int 和 Integer、double 和 Double 等)在 Java 中并不真正相互兼容。它们通过auto-boxing/unboxing的额外步骤变得兼容。因此,如果您有一个原始整数流,并且如果您尝试使用 Stream 和 Function(即 Stream 和 Function)的对象版本,您将承担装箱和拆箱元素的成本。为了消除这个问题,函数包包含流的原始专用版本以及函数接口。例如,Stream<Integer>
您应该使用,而不是使用IntStream
。您现在可以使用 处理流的每个元素IntFunction
。这将完全避免自动装箱/拆箱。
Thus, whenever you want to process streams of primitive elements, you should use the primitive specialized streams (i.e. IntStream, LongStream, and DoubleStream) and primitive specialized functional interfaces (i.e. IntFunction, IntConsumer, IntSupplier, etc.) to achieve better performance.
因此,无论何时要处理原始元素的流,都应使用原始专用流(即 IntStream、LongStream 和 DoubleStream)和原始专用功能接口(即 IntFunction、IntConsumer、IntSupplier 等)以获得更好的性能。
One more thing to note is that none of the primitive specialized functional interfaces (such as IntFunction, DoubleFunction, or IntConsumer) extend the non-primitive functional interfaces (i.e. Function, Consumer, and so on).
还要注意的另一件事是,没有任何原始专用功能接口(例如 IntFunction、DoubleFunction 或 IntConsumer)扩展非原始功能接口(即 Function、Consumer 等)。
java.util.function package
contains int, double, and long (but no float) versions of all the functional interfaces. For example, there is an IntFunction, a DoubleFunction, and a LongFunction
, which are int, double, and long, versions of Function. These functions are used along with primitive specialized versions of streams such as IntStream, DoubleStream, and LongStream.
java.util.function package
包含所有功能接口的 int、double 和 long(但没有 float)版本。例如,有一个 IntFunction、一个 DoubleFunction 和 a LongFunction
,它们是函数的 int、double 和 long 版本。这些函数与流的原始专用版本(例如 IntStream、DoubleStream 和 LongStream)一起使用。
Let's take some examples:
让我们举一些例子:
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
As a conclusion, the reason you might use mapToObj
is the same as you might use mapToInt
, which is to change the Stream type.
作为结论,您可能使用的原因与您可能使用的原因mapToObj
相同mapToInt
,即更改 Stream 类型。