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