Java Spliterator interface is an internal iterator that breaks the stream into the smaller parts. These smaller parts can be processed in parallel.
In real life programming, we may never need to use Spliterator directly. Under normal operations, it will behave exactly same as Java Iterator.
Spliterator<T> spliterator = list.spliterator();
The Java collection classes provide default stream() and parallelStream() methods which internally use the Spliterator through the call to the spliterator(). It helps in processing the collection data in parallel.
default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); } default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); }
1. Java Spliterator Features
Following is a list of features provided by Spliterator in Java.
- Spliterator has been introduced in Java 8.
- It provides support for parallel processing of stream of elements for any collection.
- It provides tryAdvance() method to iterate elements individually in different threads. It helps in parallel processing.
- To iterate elements sequentially in a single Thread, use forEachRemaining() method.
- The trySplit() method is used partition the spliterator, if it is possible.
- It helps in combining the
hasNext()
andnext()
operations into one method.
2. Java Spliterator Methods
- int characteristics() : returns the list of characteristics of the spliterator. It can be any of ORDERED, DISTINCT, SORTED, SIZED, NONNULL, IMMUTABLE, CONCURRENT, and SUBSIZED.
- long estimateSize() : returns an estimate of the number of elements that would be encountered by a forEachRemaining() traversal, or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.
- default void forEachRemaining(Consumer action) : performs the given action for each remaining element, sequentially in the current thread, until all elements have been processed or the action throws an exception.
- default Comparator getComparator() : if the spliterator’s source is SORTED by a Comparator, returns that Comparator.
- default long getExactSizeIfKnown() : returns estimateSize() if this Spliterator is SIZED, else -1.
- default boolean hasCharacteristics(int characteristics) : returns true if the dpliterator’s characteristics() contain all of the given characteristics.
- boolean tryAdvance(Consumer action) : if a remaining element exists, performs the given action on it, returning
true
; else returnsfalse
. - Spliterator trySplit() : if the spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.
3. Java Spliterator Example
3.1. Spliterator characteristics() example
Java example to verify the characteristics of Spliterator obtained for ArrayList.
ArrayList<String> list = new ArrayList<>(); Spliterator<String> spliterator = list.spliterator(); int expected = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; System.out.println(spliterator.characteristics() == expected); //true if (spliterator.hasCharacteristics(Spliterator.ORDERED)) { System.out.println("ORDERED"); } if (spliterator.hasCharacteristics(Spliterator.DISTINCT)) { System.out.println("DISTINCT"); } if (spliterator.hasCharacteristics(Spliterator.SORTED)) { System.out.println("SORTED"); } if (spliterator.hasCharacteristics(Spliterator.SIZED)) { System.out.println("SIZED"); } if (spliterator.hasCharacteristics(Spliterator.CONCURRENT)) { System.out.println("CONCURRENT"); } if (spliterator.hasCharacteristics(Spliterator.IMMUTABLE)) { System.out.println("IMMUTABLE"); } if (spliterator.hasCharacteristics(Spliterator.NONNULL)) { System.out.println("NONNULL"); } if (spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { System.out.println("SUBSIZED"); }
Program Output.
true ORDERED SIZED SUBSIZED
3.2. Spliterator estimateSize() and getExactSizeIfKnown() example
Java example to get the size of backing collection i.e. number of elements to iterate by spliterator.
ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); Spliterator<String> spliterator = list.spliterator(); System.out.println(spliterator.estimateSize()); System.out.println(spliterator.getExactSizeIfKnown());
Program Output.
4 4
3.3. Spliterator getComparator() example
Java example to find the comparator used by spliterator.
SortedSet<String> set = new TreeSet<>( Collections.reverseOrder() ); set.add("A"); set.add("D"); set.add("C"); set.add("B"); System.out.println(set); System.out.println(set.spliterator().getComparator());
Program Output.
[D, C, B, A] java.util.Collections$ReverseComparator@7852e922
3.4. Spliterator trySplit() example
Java example to split the elements to two groups and iterate independently.
ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); list.add("E"); list.add("F"); Spliterator<String> spliterator1 = list.spliterator(); Spliterator<String> spliterator2 = spliterator1.trySplit(); spliterator1.forEachRemaining(System.out::println); System.out.println("========"); spliterator2.forEachRemaining(System.out::println);
Program Output.
D E F ======== A B C
3.5. Spliterator forEachRemaining() example
Java example to perform hasNext() and next() operations in single statement using forEachRemaining() method.
ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); Spliterator<String> spliterator = list.spliterator(); spliterator.forEachRemaining(System.out::println);
Program Output.
A B C D
4. Conclusion
In this tutorial, we learned the Java Spliterator interface. We learned the Spliterator methods and simple examples to iterate over collections elements and streams apart from other useful methods in Spliterator.
Drop me your questions in comments section.
Happy Learning !!
References: