JVM Languages

Parallel Array Operations in Java 8

The new release of Java makes it simple to perform parallel operations on arrays  leading to substantially better performance with minimal additional code.

Arrays.parallelSetAll()

The new parallelSetAll() method creates an array and sets each element's value with a given generator function, using concurrency for added efficiency and performance. This method relies on lambdas (called "closures" in other languages), which is another new feature of JDK 8 that will be discussed in future articles. Suffice it to say, lambdas, whose syntax is recognizable by the -> operator, perform an operation on the right of the arrow operator for every element passed to them. In the code example below, it's for every element in the array, indexed by i. Array.parallelSetAll() generates the elements of the array. For instance, the following code loads a large array with random integer values:

We'll start with getNextSensorValue, which in reality will query a sensor (for example, temperature) for its latest reading. This sample simply generates a random value for illustration. Next, the customGenerator() method generates an array element using custom logic according to your use case. Here, it's simple addition, but in a real use case, it could be something more involved.

What's A Spliterator?

Another addition to the Arrays class that uses concurrency and lambdas is the Spliterator, which is used to traverse and break apart an array. It's not limited to just arrays; it works on Collection classes and IO channels as well. Spliterators work by automatically breaking up an array into separate pieces, with new Spliterators assigned to perform operations on the associated subarrays. The term is derived from an Iterator that "splits" its traversal work into pieces. Using our sample data from above, we can perform a spliterated action on our array like this:

Performing actions on data this way takes advantage of parallelism. You can adjust the parameters of the Spliterator, such as the minimum size of each subarrray.

Stream Processing

Finally, from an Array, you can create a Stream object that allows for parallel processing on a set of data as a whole, treated as a stream. The difference between a Collection of data and a JDK8 Stream of data is that a Collection allows you to manage the elements individually, whereas a Stream doesn't. For example, using a Collection, you can add elements, remove them, access them, and insert them in the middle. A Stream doesn't allow you to manipulate individual elements of the data set, but instead allows you to perform aggregate functions on the data as a whole. You can perform useful operations such as pulling out only distinct values (ignoring duplicates) from a set, data conversions, finding min and max values, map-reduce functions, and other mathematical operations. The following simple example uses concurrency to parallel process an array of data and sum the elements:

Conclusion

Java 8 will certainly be one of the most useful updates to the language. The parallel features mentioned here, the lambdas, and many other enhancements will be the subjects of considerable coverage in Dr. Dobb's as the unveiling date for Java 8 approaches.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!