Collections.emptyList().spliterator() is not ORDERED
paul.sandoz at oracle.com
Mon Sep 7 08:45:50 UTC 2015
Well spotted. We made an exception when the spliterator covers no elements:
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 .
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.
On 6 Sep 2015, at 12:21, Tagir F. Valeev <amaembo at gmail.com> wrote:
> 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:
> // 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();
> .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