Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java Spliterator: split traversal without inventing characteristics

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A Spliterator traverses elements and may partition the remaining traversal; its characteristic flags describe promises about that source.

Download Java source kit

The complete program targets Java 8. Compile it as one source file; its output is checked against the lesson.

Split the remaining work

A receipt batch is an ordered list. trySplit hands out a portion of the unvisited elements while leaving the rest on the original spliterator. Consume both parts to cover the batch. Consuming only the original after a successful split loses the elements transferred to the returned object.

This program checks the sum after consuming both parts; it does not assume a particular split size. A spliterator may return null, so callers must still consume the original when partitioning is unavailable. Splitting alone does not create threads or schedule tasks.

Flags are contracts

ORDERED does not mean sorted. SIZED means the estimate is exact under its contract; SUBSIZED extends the size promise to splits. A custom spliterator that declares an unsupported property can cause downstream operations to rely on evidence it did not supply.

The fixture avoids source mutation during traversal. Fail-fast detection is not a concurrency protocol. A parallel stream also needs independent operations and a suitable source; adding parallel() to a shared mutable accumulator creates a separate correctness problem.

Working program

Java
import java.util.Arrays;
import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicInteger;
public class PartitionedReceiptAmounts {
    public static void main(String[] args) {
        Spliterator<Integer> remaining = Arrays.asList(12, 18, 25, 45).spliterator();
        Spliterator<Integer> prefix = remaining.trySplit();
        AtomicInteger total = new AtomicInteger();
        if (prefix != null) prefix.forEachRemaining(total::addAndGet);
        remaining.forEachRemaining(total::addAndGet);
        System.out.println(total.get());
        System.out.println(remaining.hasCharacteristics(Spliterator.ORDERED));
    }
}

Output

Output
100
true

Costs and boundaries

Traversal visits n elements in O(n) time. The sequential example keeps bounded accumulator state; the source list stores n elements. Actual split costs depend on the source, and a linked structure can partition differently from an array-backed one.

Common Mistakes

  • Consume both returned and remaining partitions.
  • Do not label unsorted data SORTED.
  • Splitting is not thread execution.

Read next

Java streams: lazy pipelines and bounded results, Java ArrayList and indexed access, Java LinkedList: operations, internals and failure cases.

java
spliterator-contracts
Storage details