地图和mapToObj之间的Java Stream差异

时间:2017-12-14 07:10:04

标签: java java-8 java-stream

我觉得Java 8 Streams中的map()mapToObj()方法之间没有区别。在两者中我们都可以创建对象并将对象返回到流中,因此为什么这些方法存在为两个,而不仅仅是一个。

你能用例子给我解释吗?

2 个答案:

答案 0 :(得分:32)

你会看到这种酷炫的模式。 Stream类包括IntStreamLongStreamDoubleStream等。这样您就可以在流操作中使用基本类型。因为否则您必须使用Stream<Integer>Stream<Double>,这将设置值。

同样,map方法也可以这样做。在Stream<T>课程中,有mapToIntmapToDouble方法,但IntStreamDoubleStream类的情况略有不同。

IntStream中,map方法采用IntUnaryOperator,将int映射到int。如果要将流映射到Stream<T>,则必须使用mapToObjmapToObj是一个好名字,因为它区别于映射到整数的map。它表示流从IntStream更改为Stream<T>mapToObj被命名的原因与mapToInt被命名的原因相同 - 表示Stream类型/

中的更改

答案 1 :(得分:12)

数据类型的primitiveobject版本(即int和Integer,double和Double等)在Java中并不真正相互兼容。通过auto-boxing/unboxing的额外步骤使它们兼容。因此,如果您有一个原始整数流并且如果您尝试使用Stream和Function的对象版本(即流和函数,则会产生装箱和拆箱的成本。

要消除此问题,功能包包含primitive specialized versions of streams以及functional interfaces。例如,您应该使用Stream<Integer>而不是IntStream。您现在可以使用IntFunction处理流的每个元素。这样可以完全避免自动装箱/拆箱。

因此,每当您想要处理原始元素流时,您应该使用原始专用流(即IntStream,LongStream和DoubleStream)和原始专用功能接口(即IntFunction,IntConsumer,IntSupplier等)来实现更好的性能

还有一点需要注意的是,没有任何原始的专用功能接口(如IntFunction,DoubleFunction或IntConsumer)扩展非原始功能接口(即Function,Consumer等)。

java.util.function package包含所有功能接口的int,double和long(但没有浮点)版本。例如,有一个IntFunction,一个DoubleFunction和一个LongFunction,它们是Function的int,double和long版本。这些函数与流的原始专用版本一起使用,例如IntStream,DoubleStream和LongStream。

我们举一些例子:

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

总之,您使用mapToObj的原因与您使用mapToInt的原因相同,即更改流类型。