Calculating distance with a Java 8 Collector

Calculating distance with a Java 8 Collector

In a previous post I showed a way to calculate the total distance of a GPX track using Scala’s foldLeft. Continuing my current hobby of exploring the new Java 8 lambdas and streams API I thought I would see how the functional approach translated to Java.

To recap, a GPX track is just a sequence of latitude, longitude pairs. The first problem is that Java doesn’t have Scala’s handy tuples so we need a custom class to represent a point.

My first thought was to use the reduce method on the Stream interface but given the slightly more complicated requirement to keep track of both the total distance and the previous point I ended up implementing a custom Collector. From the Javadoc a Collector is:

A mutable reduction operation that accumulates input elements into a mutable result container, optionally transforming the accumulated result into a final representation after all input elements have been processed. Reduction operations can be performed either sequentially or in parallel.

The Collector interface has three type parameters: T is the type of input elements to the reduction operation, A is the mutable accumulation type of the reduction operation and R is the result type of the reduction operation.

In our case, the input elements are Points and the result type is a Double (distance in miles). We just need a mutable accumulation type to keep track of the total distance and the last point in the track. Here it is:

So we have an input type and an accumulation type. Now we can implement the Collector which uses the haversine formula to calculate great circle distance between each point in the track and put it all together:

So given that we need to implement a Point class and a custom Collector the end result isn’t quite as concise as Scala but it’s still a nice functional way of processing the list. Unfortunately we can’t take advantage of parallel streams as the points have to be processed in order. The more I use Java 8’s new streams and lambdas the more I like them and Collectors are a nice way of customising reduction.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.