Spliterator
instance is used to traverse and partition the elements of a source. Array,
Collection, IOChannel etc., come under spliterator source.
Example
1: Traverse the List
elements using spliterator.
List<Integer> primesList = Arrays.asList(2, 3, 5, 7, 11);
primesList.spliterator().forEachRemaining(System.out::println);
Example
2: Partition the
elements of spliterator.
'trySplit'
method splits the current spliterator’s elements into two parts if possible and
returns a new Spliterator object covering some portion of the elements, or null
if this spliterator cannot be split.
SpliteratorPartition.java
package com.sample.app;
import java.util.Arrays;
import java.util.Spliterator;
public class SpliteratorPartition {
public static void main(String[] args) {
Spliterator<Integer> spliterator1 = Arrays.asList(2, 3, 5, 7, 11, 13).spliterator();
Spliterator<Integer> spliterator2 = spliterator1.trySplit();
System.out.println("Elements in spliterator 1");
spliterator1.forEachRemaining(System.out::println);
System.out.println("\nElements in spliterator 2");
spliterator2.forEachRemaining(System.out::println);
}
}
Output
Elements in spliterator 1
7
11
13
Elements in spliterator 2
2
3
5
As you see
above output, spliterator1 is initially hold 6 elements (2, 3, 5, 7, 11, 13).
After the split, spliterator1 holds (7, 11, 13) and spliterator 2 holds (2, 3,
5).
Spliterator
traversal
You can
traverse the spliterator in two ways.
a.
Traverse individually using tryAdvance method
b. Traverse
sequentially in bulk using forEachRemaining method
Traverse
individually using tryAdvance method
while
(spliterator1.tryAdvance(element -> System.out.println(element))) {}
Find the
below working application.
SpliteratorTraverseOneByOne.java
package com.sample.app;
import java.util.Arrays;
import java.util.Spliterator;
public class SpliteratorTraverseOneByOne {
public static void main(String[] args) {
Spliterator<Integer> spliterator1 = Arrays.asList(2, 3, 5, 7, 11, 13).spliterator();
while (spliterator1.tryAdvance(element -> System.out.println(element))) {
}
}
}
Output
2
3
5
7
11
13
Traverse
sequentially in bulk using forEachRemaining method
Example
spliterator1.forEachRemaining(System.out::println);
SpliteratorTraverseInBulk.java
package com.sample.app;
import java.util.Arrays;
import java.util.Spliterator;
public class SpliteratorTraverseInBulk {
public static void main(String[] args) {
Spliterator<Integer> spliterator1 = Arrays.asList(2, 3, 5, 7, 11, 13).spliterator();
spliterator1.forEachRemaining(System.out::println);
}
}
Output
2
3
5
7
11
13
Split
the data using trySplit method
'trySplit'
method splits the current spliterator’s elements into two parts if possible and
returns a new Spliterator object covering some portion of the elements, or null
if this spliterator cannot be split. You can depict the same from below figure.
Find the
below working application.
SpliteratorTrySplit.java
package com.sample.app;
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
public class SpliteratorTrySplit {
private static List<Integer> nElements(int noOfElements) {
List<Integer> result = new ArrayList<>();
for (int i = 1; i < noOfElements + 1; i++) {
result.add(i);
}
return result;
}
private static void printElements(Spliterator<?> spliterator, String message) {
System.out.println(message);
spliterator.forEachRemaining(ele -> System.out.print(ele + " "));
System.out.println();
}
public static void main(String[] args) {
List<Integer> list1 = nElements(16);
Spliterator<Integer> spliterator1 = list1.spliterator();
printElements(spliterator1, "spliterator1 elements");
System.out.println("\nSplit the spliterator once");
spliterator1 = list1.spliterator();
Spliterator<Integer> spliterator2 = spliterator1.trySplit();
printElements(spliterator1, "spliterator1 elements");
printElements(spliterator2, "spliterator2 elements");
System.out.println("\nSplit the spliterator1 twice and spliterator2 twice");
spliterator1 = list1.spliterator();
spliterator2 = spliterator1.trySplit();
Spliterator<Integer> spliterator3 = spliterator1.trySplit();
Spliterator<Integer> spliterator4 = spliterator2.trySplit();
printElements(spliterator1, "spliterator1 elements");
printElements(spliterator2, "spliterator2 elements");
printElements(spliterator3, "spliterator3 elements");
printElements(spliterator4, "spliterator4 elements");
}
}
Output
spliterator1 elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Split the spliterator once
spliterator1 elements
9 10 11 12 13 14 15 16
spliterator2 elements
1 2 3 4 5 6 7 8
Split the spliterator1 twice and spliterator2 twice
spliterator1 elements
13 14 15 16
spliterator2 elements
5 6 7 8
spliterator3 elements
9 10 11 12
spliterator4 elements
1 2 3 4
Spliterator
Characteristics
A
Spliterator reports a set of characteristics of its structure, source, and
elements. Following table summarizes the characteristics of the spliterator.
Characteristic
|
Description
|
ORDERED
|
Iterate
over the elements in order.
|
DISTINCT
|
For each
pair of encountered elements x, y, !x.equals(y). This applies for example, to
a Spliterator based on a Set.
|
SORTED
|
Characteristic
value signifying that encounter order follows a defined sort order.
|
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.
|
NONNULL
|
Characteristic
value signifying that the source guarantees that encountered elements will
not be null. (This applies, for example, to most concurrent collections,
queues, and maps.)
|
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. A Spliterator that does not report IMMUTABLE
or CONCURRENT is expected to have a documented policy (for example throwing
ConcurrentModificationException) concerning structural interference detected
during traversal.
|
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. If so, the Spliterator is expected to have
a documented policy concerning the impact of modifications during traversal.
|
SUBSIZED
|
Characteristic
value signifying that all Spliterators resulting from trySplit() will be both
SIZED and SUBSIZED. This means that all child Spliterators, whether direct or
indirect, will be SIZED.
|
Find the
below working application to get the characteristics of a spliterator.
SpliteratorCharacterstics.java
package com.sample.app.streams;
import java.util.Arrays;
import java.util.List;
import java.util.Spliterator;
public class SpliteratorCharacterstics {
public static void main(String[] args) {
List<Integer> primesList = Arrays.asList(2, 3, 5, 7, 11);
Spliterator<Integer> spliterator = primesList.spliterator();
System.out.println("is ORDERED ? " + spliterator.hasCharacteristics(Spliterator.ORDERED));
System.out.println("is DISTINCT ? " + spliterator.hasCharacteristics(Spliterator.DISTINCT));
System.out.println("is SORTED ? " + spliterator.hasCharacteristics(Spliterator.SORTED));
System.out.println("is SIZED ? " + spliterator.hasCharacteristics(Spliterator.SIZED));
System.out.println("is NONNULL ? " + spliterator.hasCharacteristics(Spliterator.NONNULL));
System.out.println("is IMMUTABLE ? " + spliterator.hasCharacteristics(Spliterator.IMMUTABLE));
System.out.println("is CONCURRENT ? " + spliterator.hasCharacteristics(Spliterator.CONCURRENT));
System.out.println("is SUBSIZED ? " + spliterator.hasCharacteristics(Spliterator.SUBSIZED));
}
}
Output
is ORDERED ? true
is DISTINCT ? false
is SORTED ? false
is SIZED ? true
is NONNULL ? false
is IMMUTABLE ? false
is CONCURRENT ? false
is SUBSIZED ? true
Previous
Next
Home