javalate-bindingspliterator

Why is Spliterators.spliteratorUnknownSize() not late-binding?


I read up on spliterators today and implemented one using Spliterators.spliteratorUnknownSize(iterator(), Spliterator.NONNULL). According to spliteratorUnknownSize()'s documentation

The [resulting] spliterator is not late-binding

Being new to spliterators I am wondering why that is the case. If I ensure iterator() to be late-binding, the resulting spliterator should also be, no? spliteratorUnknownSize() is merely creating an IteratorSpliterator which does not bind to the element source yet.

I.e., I would love to understand why the resulting spliterator is not late-binding. Thank you.


Solution

  • According to the javadocs:

    "A Spliterator that does not report IMMUTABLE or CONCURRENT is expected to have a documented policy concerning: when the Spliterator binds to the element source; and detection of structural interference of the element source detected after binding. A late-binding Spliterator binds to the source of elements at the point of first traversal, first split, or first query for estimated size, rather than at the time the Spliterator is created. A Spliterator that is not late-binding binds to the source of elements at the point of construction or first invocation of any method. Modifications made to the source prior to binding are reflected when the Spliterator is traversed. After binding a Spliterator should, on a best-effort basis, throw ConcurrentModificationException if structural interference is detected. ..."

    So if you parse that carefully, late-binding versus non-late-binding is really about when detection of structural interference kicks in.

    A Spliterator wrapping an arbitrary iterator cannot guarantee to detect structural interference. It depends on how the Iterator is implemented. And even for Iterators that do detect (or mitigate) structural interference, the Spliterator cannot make any guarantees about when the detection starts; i.e. when the "binding" occurs.

    In short, it cannot guarantee true late-binding semantics.


    If I ensure iterator() to be late-binding, the resulting Spliterator should also be, no?

    The javadocs don't guarantee that.

    In practice: it probably should be, though it depends on the implementation of Spliterators. But making such a statement in the javadocs may constrain the implementation of future versions of the Spliterators class and its nested classes in ways that are harmful.


    You may disagree with my analysis. However the authors of the javadocs have clearly and deliberately stated that these Spliterators are not late bound. If you think they are wrong about that, raise a Bug Report against the javadocs.