1. Introduction
In this tutorial, we’ll discuss Spliterator
interface. This is one of the items added in Java 8 for parallel processing.
The Spliterator
interface was added in Java 8. Its name stands for “splitable iterator”. Spliterators, like Iterators, are for traversing the elements of a source. Spliterators can traverse the elements of a source in parallel. Java 8 provides a default Spliterator implementation for all data structures of Collections Framework. The Spliterator
can work with an array, a Collection, an IO channel, or a generator function.
A Spliterator may traverse elements individually using method tryAdvance()
or sequentially in bulk using method forEachRemaining()
. However, one method trySplit()
is of particular interest which may partition some of its elements as another Spliterator
to do possible-parellel operations.
A Spliterator
should, on a best-effort basis, throw ConcurrentModificationException
if structural interference is detected after binding.
Spliterators can provide an estimate of the number of remaining elements via the estimateSize() method. Spliterators are commonly used in parallel processing of elements but spliterators are not expected to be thread-safe. So we have to ensure that the spliterator is only used by one thread at a time. The behaviour of splitting and traversal is undefined if two or more threads operate concurrently on the same spliterator. Primitive subtype specializations of Spliterator are provided for int
, long
, and double
values, for example, Spliterator.OfInt.tryAdvance(java.util.function.IntConsumer)
.
2. Methods of Spliterator
- int characteristics()
- long estimateSize()
- default void forEachRemaining(Consumer action)
- default Comparator getComparator()
- default long getExactSizeIfKnown()
- default boolean hasCharacteristics(int characteristics)
- boolean tryAdvance(Consumer action)
- Spliterator trySplit()
3. The Spliterator characteristics
The Spliterator
can be better controlled and its usage can be optimized by using characteristics. The int characteristics()
method returns a set of characteristics of this Spliterator
and its elements.
Following are the characteristics of the Spliterator
interface:
static int CONCURRENT | Characteristic value signifying that the element source may be safely concurrently modified (allowing additions, replacements, and/or removals) by multiple threads without external synchronization. |
static int DISTINCT | Characteristic value signifying that, for each pair of encountered elements x, y, !x.equals(y). |
static int IMMUTABLE | Characteristic value signifying that the element source cannot be structurally modified; that is, elements cannot be added, replaced, or removed, so such changes cannot occur during traversal. |
static int NONNULL | Characteristic value signifying that the source guarantees that encountered elements will not be null. |
static int ORDERED | Characteristic value signifying that an encounter order is defined for elements. |
static int SIZED | Characteristic value signifying that the value returned from estimateSize() prior to traversal or splitting represents a finite size that, in the absence of structural source modification, represents an exact count of the number of elements that would be encountered by a complete traversal. |
static int SORTED | Characteristic value signifying that encounter order follows a defined sort order. |
static int SUBSIZED | Characteristic value signifying that all Spliterators resulting from trySplit() will be both SIZED and SUBSIZED. |
3. Example of Spliterator
Following is an example of Spliterator:
ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(1); numbers.add(2); numbers.add(3); numbers.add(4); numbers.add(5); // Create a Spliterator from the ArrayList Spliterator<Integer> spliterator = numbers.spliterator(); // Process the first half of the elements Spliterator<Integer> firstHalf = spliterator.trySplit(); firstHalf.forEachRemaining(System.out::println); // Process the second half of the elements Spliterator<Integer> secondHalf = spliterator; secondHalf.forEachRemaining(System.out::println);
4. Conclusion
The Spliterator introduced in Java 8 is one of the key things to know in Java 8 which can help in parallel processing of elements of a collection. However, it is less popular feature but it is important for interview point of view.