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
No comments:
Post a Comment