A Java Spliterator interface (also known as a splittable iterator) is an interface that's used to traverse the elements of a source (for example, a collection or stream) in parallel. This interface defines the following methods:
public interface Spliterator<T> {
boolean tryAdvance(Consumer<? super T> action);
Spliterator<T> trySplit();
long estimateSize();
int characteristics();
}
Let's consider a simple list of 10 integers:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
We can obtain a Spliterator interface for this list like so:
Spliterator<Integer> s1 = numbers.spliterator();
We can also do the same from a stream:
Spliterator<Integer> s1 = numbers.stream().spliterator();
In order to advance to (traverse) the first element, we need to call the tryAdvance() method, as follows:
s1.tryAdvance(e
-> System.out.println("Advancing to the
first element of s1: " + e));
We will receive the following output:
Advancing to the first element of s1: 1
Spliterator can try to estimate the number of elements left to traverse via the estimateSize() method, as follows:
System.out.println(" Estimated size of s1: " + s1.estimateSize());
We will receive the following output (we've traversed one element; there are nine to go):
Estimated size of s1: 9
We can split this into two via a Spliterator interface using the trySplit() method. The result will be another Spliterator interface:
Spliterator<Integer> s2 = s1.trySplit();
Checking the number of elements reveals the effect of trySplit():
System.out.println("Estimated size s1: " + s1.estimateSize());
System.out.println("Estimated size s2: " + s2.estimateSize());
We will receive the following output:
Estimated size s1: 5
Estimated size s2: 4
Trying to print all the elements from s1 and s2 can be accomplished using forEachRemaining(), as follows:
s1.forEachRemaining(System.out::println); // 6, 7, 8, 9, 10
s2.forEachRemaining(System.out::println); // 2, 3, 4, 5
A Spliterator interface defines a suite of constants for its characteristics – CONCURRENT (4096), DISTINCT (1), IMMUTABLE (1024), NONNULL (256), ORDERED (16), SIZED (64), SORTED (4), and SUBSIZED (16384).
We can print the characteristics via the characteristics() method as follows:
System.out.println(s1.characteristics()); // 16464
System.out.println(s2.characteristics()); // 16464
It is simpler to test whether a certain characteristic is presented using hasCharacteristics():
if (s1.hasCharacteristics(Spliterator.ORDERED)) {
System.out.println("ORDERED");
}
if (s1.hasCharacteristics(Spliterator.SIZED)) {
System.out.println("SIZED");
}