Loose end: spliterator() and stream() methods on Iterable
Brian Goetz
brian.goetz at oracle.com
Tue Jun 25 09:50:11 PDT 2013
This comes back to the "unknown Q" problem. If the user is doing some
high-Q stream operation, then even the crappy parallelism offered by
splitting iterators is likely to be a win. Since a means for knowing Q
seems years off, we have two choices:
A: Do what the user asked. If the user asked for something stupid, he
gets something stupid.
B: Try to save the user from himself through heuristics. This includes
suggestions like "always make Spliterators from Iterators sequential" or
"make parallel limit sequential".
For most of these choices, we've chosen (A). (B is definitely a
lifetime subscription to Whack A Mole Digest.)
On 6/25/2013 12:44 PM, Doug Lea wrote:
> On 06/25/13 11:27, Brian Goetz wrote:
>> As I try to specify even this small addition, I'm still not sure :(
>>
>> The default implementation -- which is just
>>
>> return Spliterators.spliteratorUnknownSize(iterator(), 0);
>>
>> should almost always be overriden. It has crappy parallelism, doesn't
>> know its
>> size, doesn't know any other spliterator characteristics, and is
>> early-binding
>> -- the "grand slam" of bad spliterators.
>
> How about having this Spliterator always return null on trySplit?!
> That way, they won't get crappy parallelism, they get no parallelism.
>
> -Doug
>
>
>
>
>
>>
>> The downside is that people will not override spliterator() and result
>> in bad
>> streams. The upside is that then Iterable *has* a spliterator()
>> method, which
>> reduces the effort for *clients* to make streams out of Iterables.
>>
>> Here's what I've got so far:
>>
>> /**
>> * Creates a {@link Spliterator} over the elements described by this
>> * {@code Iterable}.
>> *
>> * @implSpec
>> * <p>The default implementation should almost always be
>> overridden. The
>> * spliterator returned by the default implementation has poor
>> splitting
>> * characteristics, is unsized (and does not report any other
>> spliterator
>> * characteristics), and is <em><a
>> href="Spliterator.html#binding">early-binding</a></em>.
>> * Implementating classes can nearly always provide a better
>> implementation.
>> * The returned spliterator inherits the <em>fail-fast</em>
>> properties of the
>> * collection's iterator.
>> *
>> * @return a {@code Spliterator} over the elements described by this
>> * {@code Iterable}.
>> * @since 1.8
>> */
>> default Spliterator<T> spliterator() {
>> return Spliterators.spliteratorUnknownSize(iterator(), 0);
>> }
>>
>>
>>
>> On 6/25/2013 6:39 AM, Paul Sandoz wrote:
>>>
>>> On Jun 24, 2013, at 11:41 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>>>
>>>> On 06/24/2013 09:40 PM, Brian Goetz wrote:
>>>>> After further thought, I think what this means is that we can move
>>>>> spliterator() up to Iterable, but not stream(). The reason for
>>>>> this is that
>>>>> some classes that implement Iterable<Integer> might prefer that their
>>>>> stream() method return an IntStream, not be forced into a
>>>>> Stream<Integer>.
>>>>> So putting stream() too high up in the hierarchy forecloses on this.
>>>>
>>>> I agree,
>>>
>>> +1
>>>
>>> Paul.
>>>
>>>
>>>> Spliterator.OfInt is a Spliterator but IntStream is not a Stream.
>>>>
>>>> Rémi
>>
>
>
More information about the lambda-libs-spec-observers
mailing list