Collections.emptyList().spliterator() is not ORDERED
Paul Sandoz
paul.sandoz at oracle.com
Mon Sep 7 08:45:50 UTC 2015
Hi Tagir,
Well spotted. We made an exception when the spliterator covers no elements:
https://bugs.openjdk.java.net/browse/JDK-8022797
http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/737b6c298d81
I thought i could get away solely with a specification change to allow reuse of an empty spliterator implementation. But, as you show it pops up in certain cases that aggregate two or more streams. In hindsight i somewhat regret this decision as it makes general processing more difficult :-(
In this case we should fix Stream.concat to check if a spliterator reporting SIZED is empty, which will allow us to optimize the concatenation [1].
Paul.
P.S. I still have a bunch of your stuff in my queue to process, sorry it’s taking so long,i will get to them in the next couple of weeks, but i need to process some other stuff first.
[1] https://bugs.openjdk.java.net/browse/JDK-8022805
On 6 Sep 2015, at 12:21, Tagir F. Valeev <amaembo at gmail.com> wrote:
> Hello!
>
> As Paul Sandoz pointed out in the "Custom spliterator for
> Collections.nCopies(n, obj).stream()" discussion, the
> List.spliterator() is specified to be ORDERED. However
> Collections.emptyList().spliterator() violates this specification:
>
> System.out.println(Collections.emptyList()
> .spliterator().hasCharacteristics(Spliterator.ORDERED));
> // prints false
>
> This becomes critical if I want to concatenate streams from the two
> lists returned from two different methods (one of which returned
> emptyList) and process the result in parallel. For example:
>
> List<Integer> list1 = IntStream.range(0, 100).boxed().collect(Collectors.toList());
> List<Integer> list2 = Collections.emptyList();
> System.out.println(Stream
> .concat(list1.stream(), list2.stream()).parallel()
> .filter(x -> x >= 0).limit(10).collect(Collectors.toList()));
>
> This code unexpectedly prints some random subset. This can be fixed by
> replacing list2 with
>
> List<Integer> list2 = Arrays.asList();
>
> As Arrays.asList().spliterator() is ordered, the resulting stream is
> ordered as well, so we see [0, ..., 9] as expected.
>
> Looks like a bug in emptyList() implementation.
>
> With best regards,
> Tagir Valeev.
>
More information about the core-libs-dev
mailing list