Spliterator

Tim Peierls tim at peierls.net
Tue Dec 18 19:55:42 PST 2012


vauge -> vague

On Tue, Dec 18, 2012 at 10:36 PM, Brian Goetz <brian.goetz at oracle.com>wrote:

> Committed recommended spec and method renamings that follow all of these,
> except changing the return type of getNaturalSplits.  Committed new text
> for getNaturalSplits which hopefully should be acceptable?
>
>
> On 12/18/2012 2:02 PM, Doug Lea wrote:
>
>>
>> Having gotten Stream-compatible Spliterators to "work"
>> with ConcurrentHashMap view classes (keySet, values, entrySet),
>> here's a another try at recommending some reworking of
>> the Spliterator interface.
>>
>> This time, I'm trying hard to make the smallest
>> changes that support what Brian et al are already doing.
>> (Although changing one of those things.)
>> Pasted below (minus top-level javadoc, that would need
>> at most a small touch-ip.)
>>
>> Main issues:
>>
>> 1. At the moment, unless you implement "sizeIfKnown"
>> of top-level Spliterator as non-negative, no splitting
>> takes place, even if you implement estimatedSize.
>> (Only implementing estimatedSize seemed like the right
>> thing to do for CHM; among other reasons because
>> its size might change while traversing. But I had
>> to lie in getSizeIfKnown to make it do approximately
>> the right thing.)
>>
>> So I tried to clearly spec the cases for
>> (renamed) "exactSize" and "estimatedSize", and
>> similarly spec (renamed) hasExactSplits.
>>
>> If we go with this (or even if not), the stream
>> implementation should be changed accordingly.
>>
>> 2. Because split() is stateful, it is unclear at
>> best what a return value > 1 for getNaturalSplits
>> might mean? All the child splits and their descendents?
>> Only the next #getNaturalSplits calls?
>> Flailing around left me with the conclusion that
>> the only sensible way to spec this is to rename as
>> boolean isSplittable(), thus clearly referring only to the
>> next call to split.
>>
>> Comments? Complaints?
>>
>>
>> public interface Spliterator<T> {
>>
>>      /**
>>       * Returns a Spliterator covering some portion of the elements,
>>       * guaranteed not to overlap with those retained by this
>>       * Spliterator. After invoking this method, the current
>>       * Spliterator will <em>not</em> cover the elements of the
>>       * returned Spliterator.
>>       *
>>       * <p>This method may throw an IllegalStateException if a
>>       * traversal via {@link #iterator} or {@link @forEach} has already
>>       * commenced.
>>       *
>>       * @return a Spliterator covering the some portion, possibly empty,
>> of the
>>       * data structure elements.
>>       * @throws IllegalStateException if traversal has already commenced
>>       */
>>      Spliterator<T> split();
>>
>>      /**
>>       * Returns {@code false} if an invocation of {@code split()} is
>>       * guaranteed to return an empty Spliterator. Otherwise the method
>>       * implementation may choose a return value based on data
>>       * structure constraints and efficiency considerations.
>>       */
>>      boolean isSplittable();
>>
>>      /**
>>       * Return the Iterator covering the remaining elements. The same
>>       * iterator instance must be returned for every invocation.  This
>>       * method initiates the traversal phase.  <p/>
>>       * @return the iterator of the remaining elements.
>>       */
>>      Iterator<T> iterator();
>>
>>      /**
>>       * Performs the given action for all remaining elements.
>>       *
>>       * @param block The action
>>       */
>>      default void forEach(Block<? super T> block) {
>>          iterator().forEach(block);
>>      }
>>
>>      /**
>>       * Returns the number of elements that would be encountered by an
>>       * {@link #iterator} or {@link @forEach} traversal, or returns a
>>       * negative value if unknown, or if computing this value may
>>       * itself require traversal or significant computation.
>>       */
>>      default long exactSize() {
>>          return -1;
>>      }
>>
>>      /**
>>       * Returns an estimate of the number of elements that would be
>>       * encountered by an {@link #iterator} or {@link @forEach}
>>       * traversal, or returns a negative value if unknown, or if
>>       * computing this value may itself require traversal or
>>       * significant computation.
>>       *
>>       * <p>For example, a sub-spliterator of an approximately balanced
>>       * tree may return a value that estimates the number of elements
>>       * to be half of that of its parent.
>>       */
>>      default long estimatedSize() {
>>          return exactSize();
>>      }
>>
>>      /**
>>       * Return {@code true} if the {@link #exactSize} method of this
>>       * Spliterator and all of those split from it return non-negative
>>       * results.
>>       */
>>      boolean hasExactSplits();
>> }
>>
>


More information about the lambda-libs-spec-observers mailing list