Primitive stream vs object stream and actual boxing that occurs

故事扮演 提交于 2019-12-10 17:23:23

问题


So I understand you can have object streams, i.e. Stream<T> and specialist primitive streams, e.g. IntStream, DoubleStream, etc. One of the benefits of the latter is to avoid autoboxing.

Also if we take IntStream as an example, it has specialised operations such as filter that accepts an IntPredicate.

I wondered if I had an IntStream vs a Stream<Integer> at which point you're saving on boxing, e.g.

intstream.filter(x -> x >= 50).forEach(x -> System.out.println(x));

vs

stream.filter(x -> x >= 50).forEach(x -> System.out.println(x));

In the first example, there is no boxing or unboxing that I can see. In the second example where is the boxing / unboxing occurring? Because if stream is a Stream<Integer> and the filter accepts a Predicate<Integer> then surely there's no need to box/unbox, and the same for IntConsumer vs Consumer<T>?


回答1:


With Stream<Integer> your stream is already boxed. So depending on how you created it there are several possibilities:

  • You have initially boxed values. For example, you had List<Integer> list as the input and wrote:

    stream = list.stream();
    
  • You boxed your values when creating the stream. For example, you created it like this:

    stream = Stream.iterate(1, x -> x+1);
    

    In this case the first argument is boxed to Integer.valueOf(1) and unboxing/boxing also occurs on every lambda (which is UnaryOperator<Integer>) invocation. So effectively you have:

    stream = Stream.iterate(Integer.valueOf(1), x -> Integer.valueOf(x.intValue()+1));
    
  • You boxed your source explicitly via upstream intermediate operation. For example:

    stream = IntStream.range(0, 1000).boxed();
    

    In this case boxing is performed inside the .boxed() operation (which is a shortcut for .mapToObj(Integer::valueOf)).




回答2:


The unboxing happens inside the predicate: in stream.filter(x -> x >= 50), the Predicate essentially becomes (Integer x) -> x.intValue() >= 50, and intValue() is the unboxing step. Additionally, System.out.println does some unboxing itself, in the implementation of Integer.toString that ends up being called.



来源:https://stackoverflow.com/questions/35209191/primitive-stream-vs-object-stream-and-actual-boxing-that-occurs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!