Java.util Interface Spliterator in Java8

30 May, 2018
Prerequisite : Iterators in java
Spliterators, like other Iterators, are for traversing the elements of a source. A source can be a Collection, an IO channel or a generator function.
It is included in JDK 8 for support of efficient parallel traversal(parallel programming) in addition to sequential traversal.
However, you can use Spliterator even if you won’t be using parallel execution. One reason you might want to do so is because it combines the hasNext and next operations into one method.
For collections, Spliterator object can be created by calling spliterator() method present in Collection interface.
// Here "c" is any Collection object. splitr is of
// type Spliterator interface and refers to "c"
Spliterator splitr = c.spliterator();

Spliterator interface defines 8 methods:
int characteristics() : Returns a set of characteristics of this Spliterator and its elements. The result is from ORDERED(0x00000010), DISTINCT(0x00000001), SORTED(0x00000004), SIZED(0x00000040), NONNULL(0x00000100), IMMUTABLE(0x00000400), CONCURRENT(0x00001000), SUBSIZED(0x00004000).Syntax : 
int characteristics()
Parameters : 
NA
Returns :
Returns the characteristics of the invoking spliterator,
encoded into an integer.
long estimateSize( ) : It returns an estimate the number of elements left to iterate or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.Syntax : 
long estimateSize( )
Parameters : 
NA
Returns :
Estimates the number of elements left to iterate and
returns the result. Returns Long.MAX_VALUE if the
count cannot be obtained for any reason.
default long getExactSizeIfKnown( ) : Convenience method that returns estimateSize() if this Spliterator is SIZED, else -1.Syntax : 
default long getExactSizeIfKnown( )
Parameters : 
NA
Returns :
If the invoking spliterator is SIZED, returns the number of
elements left to iterate. Returns –1 otherwise.
default Comparator<? super T> getComparator( ) : If this Spliterator’s source is SORTED by a Comparator, returns that Comparator. If the source is SORTED in natural order, returns null. Otherwise, if the source is not SORTED, throws IllegalStateException.Syntax : 
default Comparator<? super T> getComparator( )
Parameters : 
NA
Returns :
Returns the comparator used by the invoking spliterator
or null if natural ordering is used. 
Throws:
IllegalStateException - If the sequence is unordered, 
IllegalStateException is thrown.
default boolean hasCharacteristics(int val) : Returns true if this Spliterator’s characteristics() contain all of the given characteristics.Syntax : 
default boolean hasCharacteristics(int val)
Parameters : 
characteristics - the characteristics to check for
Returns :
Returns true if the invoking spliterator has the
characteristics passed in val. Returns false otherwise.
boolean tryAdvance(Consumer<? super T> action) : If a remaining element exists, performs the given action on it, returning true; else returns false. If this Spliterator is ORDERED the action is performed on the next element in encounter order. Exceptions thrown by the action are relayed to the caller.Syntax : 
boolean tryAdvance(Consumer<? super T> action) 
Parameters : 
action - The action
Returns :
Returns true if there is a next element. Returns false if no
elements remain.
Throws :
NullPointerException - if the specified action is null
default void forEachRemaining(Consumer<? super T>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. If this Spliterator is ORDERED, actions are performed in encounter order. Exceptions thrown by the action are relayed to the caller.Syntax : 
default void forEachRemaining(Consumer<? super T>action)
Parameters : 
action - The action
Returns :
NA
Throws :
NullPointerException - if the specified action is null
Spliterator<T> trySplit( ) : If possible, splits the invoking spliterator, returning a reference to a new spliterator for the partition. Otherwise, returns null. Thus, if successful, the original spliterator iterates over one portion of the sequence and the returned spliterator iterates over the other portion.Syntax : 
Spliterator<T> trySplit( )
Parameters : 
NA
Returns :
a Spliterator covering some portion of the elements, 
or null if this spliterator cannot be split
The below example demonstrate methods of Spliterator.// Java program to demonstrate// methods of Spliterator  import java.util.ArrayList;import java.util.Spliterator;import java.util.stream.Stream;      public class SpliteratorDemo {    public static void main(String[] args)     {        // Create an array list for doubles.        ArrayList<Integer> al = new ArrayList<>();                      // Add values to the array list.        al.add(1);        al.add(2);        al.add(-3);        al.add(-4);        al.add(5);                      // Obtain a Stream to the array list.        Stream<Integer> str = al.stream();                      // getting Spliterator object on al        Spliterator<Integer> splitr1 = str.spliterator();                  // estimateSize method        System.out.println("estimate size : " + splitr1.estimateSize());                          // getExactSizeIfKnown method        System.out.println("exact size : " + splitr1.getExactSizeIfKnown());                  // hasCharacteristics and characteristics method        System.out.println(splitr1.hasCharacteristics(splitr1.characteristics()));                  System.out.println("Content of arraylist :");        // forEachRemaining method            splitr1.forEachRemaining((n) -> System.out.println(n));                  // Obtaining another  Stream to the array list.        Stream<Integer> str1 = al.stream();        splitr1 = str1.spliterator();                  // trySplit() method        Spliterator<Integer> splitr2 = splitr1.trySplit();                  // If splitr1 could be split, use splitr2 first.        if(splitr2 != null) {        System.out.println("Output from splitr2: ");        splitr2.forEachRemaining((n) -> System.out.println(n));        }          // Now, use the splitr        System.out.println("\nOutput from splitr1: ");        splitr1.forEachRemaining((n) -> System.out.println(n));                  }}Output:estimate size : 5
exact size : 5
true
Content of arraylist :
1
2
-3
-4
5
Output from splitr2: 
1
2

Output from splitr1: 
-3
-4
5

int characteristics() : Returns a set of characteristics of this Spliterator and its elements. The result is from ORDERED(0x00000010), DISTINCT(0x00000001), SORTED(0x00000004), SIZED(0x00000040), NONNULL(0x00000100), IMMUTABLE(0x00000400), CONCURRENT(0x00001000), SUBSIZED(0x00004000).Syntax : 
int characteristics()
Parameters : 
NA
Returns :
Returns the characteristics of the invoking spliterator,
encoded into an integer.

Syntax : 
int characteristics()
Parameters : 
NA
Returns :
Returns the characteristics of the invoking spliterator,
encoded into an integer.

long estimateSize( ) : It returns an estimate the number of elements left to iterate or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.Syntax : 
long estimateSize( )
Parameters : 
NA
Returns :
Estimates the number of elements left to iterate and
returns the result. Returns Long.MAX_VALUE if the
count cannot be obtained for any reason.

Syntax : 
long estimateSize( )
Parameters : 
NA
Returns :
Estimates the number of elements left to iterate and
returns the result. Returns Long.MAX_VALUE if the
count cannot be obtained for any reason.

default long getExactSizeIfKnown( ) : Convenience method that returns estimateSize() if this Spliterator is SIZED, else -1.Syntax : 
default long getExactSizeIfKnown( )
Parameters : 
NA
Returns :
If the invoking spliterator is SIZED, returns the number of
elements left to iterate. Returns –1 otherwise.

Syntax : 
default long getExactSizeIfKnown( )
Parameters : 
NA
Returns :
If the invoking spliterator is SIZED, returns the number of
elements left to iterate. Returns –1 otherwise.

default Comparator<? super T> getComparator( ) : If this Spliterator’s source is SORTED by a Comparator, returns that Comparator. If the source is SORTED in natural order, returns null. Otherwise, if the source is not SORTED, throws IllegalStateException.Syntax : 
default Comparator<? super T> getComparator( )
Parameters : 
NA
Returns :
Returns the comparator used by the invoking spliterator
or null if natural ordering is used. 
Throws:
IllegalStateException - If the sequence is unordered, 
IllegalStateException is thrown.

Syntax : 
default Comparator<? super T> getComparator( )
Parameters : 
NA
Returns :
Returns the comparator used by the invoking spliterator
or null if natural ordering is used. 
Throws:
IllegalStateException - If the sequence is unordered, 
IllegalStateException is thrown.

default boolean hasCharacteristics(int val) : Returns true if this Spliterator’s characteristics() contain all of the given characteristics.Syntax : 
default boolean hasCharacteristics(int val)
Parameters : 
characteristics - the characteristics to check for
Returns :
Returns true if the invoking spliterator has the
characteristics passed in val. Returns false otherwise.

Syntax : 
default boolean hasCharacteristics(int val)
Parameters : 
characteristics - the characteristics to check for
Returns :
Returns true if the invoking spliterator has the
characteristics passed in val. Returns false otherwise.

boolean tryAdvance(Consumer<? super T> action) : If a remaining element exists, performs the given action on it, returning true; else returns false. If this Spliterator is ORDERED the action is performed on the next element in encounter order. Exceptions thrown by the action are relayed to the caller.Syntax : 
boolean tryAdvance(Consumer<? super T> action) 
Parameters : 
action - The action
Returns :
Returns true if there is a next element. Returns false if no
elements remain.
Throws :
NullPointerException - if the specified action is null

Syntax : 
boolean tryAdvance(Consumer<? super T> action) 
Parameters : 
action - The action
Returns :
Returns true if there is a next element. Returns false if no
elements remain.
Throws :
NullPointerException - if the specified action is null

default void forEachRemaining(Consumer<? super T>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. If this Spliterator is ORDERED, actions are performed in encounter order. Exceptions thrown by the action are relayed to the caller.Syntax : 
default void forEachRemaining(Consumer<? super T>action)
Parameters : 
action - The action
Returns :
NA
Throws :
NullPointerException - if the specified action is null

Syntax : 
default void forEachRemaining(Consumer<? super T>action)
Parameters : 
action - The action
Returns :
NA
Throws :
NullPointerException - if the specified action is null

Spliterator<T> trySplit( ) : If possible, splits the invoking spliterator, returning a reference to a new spliterator for the partition. Otherwise, returns null. Thus, if successful, the original spliterator iterates over one portion of the sequence and the returned spliterator iterates over the other portion.Syntax : 
Spliterator<T> trySplit( )
Parameters : 
NA
Returns :
a Spliterator covering some portion of the elements, 
or null if this spliterator cannot be split

Syntax : 
Spliterator<T> trySplit( )
Parameters : 
NA
Returns :
a Spliterator covering some portion of the elements, 
or null if this spliterator cannot be split

The below example demonstrate methods of Spliterator.
// Java program to demonstrate// methods of Spliterator  import java.util.ArrayList;import java.util.Spliterator;import java.util.stream.Stream;      public class SpliteratorDemo {    public static void main(String[] args)     {        // Create an array list for doubles.        ArrayList<Integer> al = new ArrayList<>();                      // Add values to the array list.        al.add(1);        al.add(2);        al.add(-3);        al.add(-4);        al.add(5);                      // Obtain a Stream to the array list.        Stream<Integer> str = al.stream();                      // getting Spliterator object on al        Spliterator<Integer> splitr1 = str.spliterator();                  // estimateSize method        System.out.println("estimate size : " + splitr1.estimateSize());                          // getExactSizeIfKnown method        System.out.println("exact size : " + splitr1.getExactSizeIfKnown());                  // hasCharacteristics and characteristics method        System.out.println(splitr1.hasCharacteristics(splitr1.characteristics()));                  System.out.println("Content of arraylist :");        // forEachRemaining method            splitr1.forEachRemaining((n) -> System.out.println(n));                  // Obtaining another  Stream to the array list.        Stream<Integer> str1 = al.stream();        splitr1 = str1.spliterator();                  // trySplit() method        Spliterator<Integer> splitr2 = splitr1.trySplit();                  // If splitr1 could be split, use splitr2 first.        if(splitr2 != null) {        System.out.println("Output from splitr2: ");        splitr2.forEachRemaining((n) -> System.out.println(n));        }          // Now, use the splitr        System.out.println("\nOutput from splitr1: ");        splitr1.forEachRemaining((n) -> System.out.println(n));                  }}
Output:
estimate size : 5
exact size : 5
true
Content of arraylist :
1
2
-3
-4
5
Output from splitr2: 
1
2

Output from splitr1: 
-3
-4
5

Java program for tryadvance method
Have a look at tryAdvance() method.It performs an action on the next element and then advances the iterator. It is shown here:
boolean tryAdvance(Consumer<? super T> action)

Here, action specifies the action that is executed on the next element in the iteration and Consumer is a functional interface that applies an action to an object. It is a generic functional interface declared in java.util.function. It has only one abstract method, accept( ), which isshown here:
void accept(T objRef)

here T is type of object reference.
For implementing our action, we must implement accept method.To implement accept method, here we use lambda expression .This will be more clear from below example.
How to use Spliterator with Collections: Using Spliterator for basic iteration tasks is quite easy, simply call tryAdvance( ) until it returns false.
// Java program to demonstrate simple Spliterator// using tryAdvance method  import java.util.ArrayList;import java.util.Spliterator;      public class SpliteratorDemo {    public static void main(String[] args)     {        // Create an array list for doubles.        ArrayList<Integer> al1 = new ArrayList<>();                      // Add values to the array list.        al1.add(1);        al1.add(2);        al1.add(-3);        al1.add(-4);        al1.add(5);                                    // Use tryAdvance() to display(action) contents of arraylist.                      System.out.print("Contents of arraylist:\n");                      // getting Spliterator object on al1        Spliterator<Integer> splitr = al1.spliterator();                      // Use tryAdvance() to display(action) contents of arraylist.        // Notice how lambda expression is used to implement accept method        // of Consumer interface                      while(splitr.tryAdvance((n) -> System.out.println(n)));                      // Use tryAdvance() for getting absolute values(action) of contents of arraylist.                                    // Create new list that contains absolute values.        ArrayList<Integer> al2 = new ArrayList<>();                                                  splitr = al1.spliterator();                      // Here our action is to get absolute values        // Notice how lambda expression is used to implement accept method        // of Consumer interface        while(splitr.tryAdvance((n) -> al2.add(Math.abs(n))));                      System.out.print("Absolute values of contents of arraylist:\n");                      // getting Spliterator object on al2        splitr = al2.spliterator();                                    while(splitr.tryAdvance((n) -> System.out.println(n)));                  }}
Output:
Contents of arraylist:
1
2
-3
-4
5
Absolute values of contents of arraylist:
1
2
3
4
5

Notice how tryAdvance( ) consolidates the purposes of hasNext( ) and next( ) provided by Iterator into a single method in above example. This improves the efficiency of the iteration process.
In some cases, you might want to perform some action on each element collectively, rather than one at a time. To handle this type of situation, Spliterator provides the forEachRemaining( ) method, it is generally used in cases involving streams. This method applies action to each unprocessed element and then returns.
This article is contributed by Gaurav Miglani. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Java - util package
Java
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.