Spliterators
JDK 8 adds a new type of
iterator called a spliterator that is
defined by the Spliterator
interface. A spliterator cycles through a sequence of elements, and in this
regard, it is similar to the iterators just described. However, the techniques
required to use it differ. Furthermore, it offers substantially more
functionality than does either Iterator
or ListIterator. Perhaps the most
important aspect of Spliterator is
its ability to provide support for parallel iteration of portions of the
sequence. Thus, Spliterator supports
parallel programming. (See Chapter 28 for information on concurrency and
parallel programming.) 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 offers a streamlined approach that
combines the hasNext and next operations into one method.
Spliterator is a generic interface that is declared like this: interface Spliterator<T>
Here, T is the type of elements being iterated. Spliterator declares the methods shown in Table 18-10.
Using Spliterator for basic iteration tasks is quite easy: simply call tryAdvance( ) until it returns false. If you will be applying the same
action to each element in the sequence, forEachRemaining(
) offers a streamlined alternative. In both cases, the action that will occur with each iteration is defined
by what the Consumer object does
with each element. Consumer is a
functional interface that applies an action to an object. It is a generic functional interface declared in java.util.function. (See Chapter 19 for
information on java.util.function.) Consumer specifies only one abstract
method, accept( ), which is shown here:
void accept(T objRef)
In the case of tryAdvance( ), each iteration passes the next element in the
sequence to objRef. Often, the
easiest way to implement Consumer is by use of a lambda expression.
The following program
provides a simple example of Spliterator.
Notice that the program demonstrates both tryAdvance(
) and forEachRemaining( ). Also
notice how these methods combine the actions of Iterator’s next( ) and hasNext( ) methods into a single call.
// A simple Spliterator demonstration.
import java.util.*;
class SpliteratorDemo {
public static void main(String args[]) {
//Create an array list for doubles.
ArrayList<Double> vals = new
ArrayList<>();
//Add values to the array list.
vals.add(1.0);
vals.add(2.0);
vals.add(3.0);
vals.add(4.0);
vals.add(5.0);
//Use tryAdvance() to display contents of vals.
System.out.print("Contents of
vals:\n");
Spliterator<Double> spltitr =
vals.spliterator();
while(spltitr.tryAdvance((n) ->
System.out.println(n)));
System.out.println();
//Create new list that contains square roots.
spltitr = vals.spliterator();
ArrayList<Double> sqrs = new ArrayList<>();
while(spltitr.tryAdvance((n) ->
sqrs.add(Math.sqrt(n))));
// Use forEachRemaining() to display contents
of sqrs.
System.out.print("Contents of
sqrs:\n");
spltitr = sqrs.spliterator();
spltitr.forEachRemaining((n) -> System.out.println(n));
System.out.println();
}
}
The output is shown here:
Contents of vals: 1.0 2.0 3.0 4.0 5.0
Contents of sqrs: 1.0 1.4142135623730951
1.7320508075688772 2.0 2.23606797749979
Although this program
demonstrates the mechanics of using Spliterator,
it does not reveal its full power. As mentioned, Spliterator’s maximum benefit is found in situations that involve
parallel processing.
In Table 18-10, notice the methods characteristics( ) and hasCharacteristics( ). Each Spliterator has a set of attributes,
called characteristics, associated
with it. These are defined by static
int fields in Spliterator, such as SORTED,
DISTINCT, SIZED, and IMMUTABLE, to
name a few. You can obtain the characteristics by calling characteristics( ). You can determine if a characteristic is
present by calling hasCharacteristics( ).
Often, you won’t need to access a Spliterator’s
characteristics, but in some cases, they can aid in creating efficient,
resilient code.
There are several nested
subinterfaces of Spliterator
designed for use with the primitive types double,
int, and long. These are called Spliterator.OfDouble,
Spliterator.OfInt, and Spliterator.OfLong. There is also a
generalized version called
Spliterator.OfPrimitive( ), which
offers additional flexibility and serves as a superinterface of the
aforementioned ones.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.