Is there any significant difference (in performance or best practices) between those two stream creation methods?
int[] arr2 = {1,2,3,4,5,6};
Arrays.stream(arr2)
.map((in)->in*2)
.mapToObj((in) -> new Integer(in))
.collect(Collectors.toCollection(()-> new ArrayList<>()));
Arrays.stream(arr2)
.map(in->in*2)
.boxed()
.collect(Collectors.toCollection(()-> new ArrayList<>()));
Thanks to Stack Community answers I can add some addons to question completeness for new readers:
As many pointed out, .boxed()
IntStream method is defined as:
@Override
public final Stream<Integer> boxed() {
return mapToObj(Integer::valueOf);
}
What basically re-defines issue to which one of following is better:
.mapToObj(in -> new Integer(in))
or
.mapToObj(in -> Integer.valueOf(in))
Yes, boxed()
uses Integer.valueOf
which can retrieve some Integer
instances from a cache.
So you should either use the version with boxed()
(preferably), or use Integer.valueOf
instead of new Integer()
. Note that boxed()
is in fact shorthand for mapToObj(Integer::valueOf)
.
The second is better as it creates no Integer
objects in this example.
From the JLS 5.1.7
If the value p being boxed is ... an int ... between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
Generally speaking, you should not call new
on wrapper types, but use their static
factory methods - for example Integer.valueOf
IntStream.boxed()
uses Integer.valueOf(int)
which is an optimised version* of Integer(int)
.
Internally, boxed()
is defined as mapToObj(Integer::valueOf)
.
*this method should generally be used in preference to the constructor
Integer(int)
, as this method is likely to yield significantly better space and time performance by caching frequently requested values.The Javadoc of
Integer.valueOf(int)
In terms of best practice, the second approach is preferable because when you want to box a primitive value boxed
is created exactly for that purpose and does so in the most optimised way possible whereas mapToObj
, although can be used to achieve the same thing, is not the idiomatic approach.
Further, it's advised not to use the primitive wrapper type constructors anymore and instead favour the valueOf
methods, this is because these constructors have been deprecated as well as the fact that by using the valueOf
it reduces memory footprint compared to the constructors leading to better performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With