The Sum of all Reductions

The reduction of all sums

Image for post
Image for post
Belmar, NJ during the Deep Freeze of 2018

During the Deep Freeze of 2018, everything in the world seemed to be reduced to ice and snow, including the sky. Even the sun seemed to be reduced as it ran away from my camera with a shiver.

This got me thinking about different kinds of reductions we have available in Java with Eclipse Collections and Java Streams. I wondered how many ways we could define sum with the various methods available.

Summing an array of ints

Let’s consider several ways we can sum the values in an int array in Java.

Here is the data we will use.

For Loop

forEach (IntStream) / each (IntList)

injectInto (IntList)

reduce (IntStream)

sum (IntStream / IntList)

Clearly, the sum methods available on IntStream and IntList are the simplest solutions. The minor difference with IntList is that the result is widened to a long which means you can add very large ints without overflowing.

Summarizing an array of ints

When we summarize using the IntSummaryStatistics class that was added in Java 8, we get the count, sum, min, max and average calculated at the same time. This saves you from iterating multiple times. We will use the same data as before.

For Loop

forEach (IntStream) / each (IntList)

injectInto (IntList)

collect (IntStream)

Note: I could not use reduce because both parameters have to be the same type. I had to use collect instead, which is a mutable reduction. The collect method on primitive Streams does not take a Collector, but instead takes a Supplier, ObjectIntConsumer (accumulator) and a BiConsumer (combiner).

summaryStatistics (IntStream / IntList)

Again, the summaryStatistics methods are the simplest solutions.

Summing the lengths of an array of Strings

Let’s say we want to sum the lengths of Strings in an array. This approach could be used for summing any int attribute of an object.

Here is the data we will use.

For Loop

For Each (Stream) / each (ImmutableList)

collectInt (ImmutableList)+ injectInto (IntList)

collect (Stream) + reducing (Collectors)

mapToInt (Stream) + Reduce (IntStream)

mapToInt (Stream) + sum (IntStream)

collectInt (ImmutableList) + sum (IntList)

collect (Stream) + summingInt (Collectors)

sumOfInt (ImmutableList)

I think in these examples, sumOfInt is the simplest solution.

Summing the lengths of Strings grouped by the first character

In this problem we will group Strings by their first character and sum the length of the Strings for each character. I will prefer to use use primitive maps here for the grouping if possible.

Here is the data.

The Stream and ImmutableList strings are converted to lowercase using map and collect, respectively. We will do this manually in the for loop example.

For Loop

for Each (Stream) / each (ImmutableList)

injectInto (ImmutableList)

reduce (Stream)

aggregateBy (ImmutableList)

aggregateInPlaceBy (ImmutableList)

collect (Stream)

collect (Stream) + groupingBy (Collectors) + summingInt (Collectors)

collect (Stream) + sumByInt (Collectors2)

reduceInPlace (ImmutableList)+ sumByInt (Collectors2)

sumByInt (ImmutableList)

The simplest solution here is sumByInt.

Conclusion

We’ve covered a lot of different approaches you can use to sum or summarize values using Java and Eclipse Collections. In the case of summing, using a method with sum in the name will probably give you the simplest solution. You can solve almost any problem using methods like injectInto and reduceInPlace (Eclipse Collections) or collect (Java Stream). Methods like reduce are less useful when your result needs to be different than your input. Methods like aggregateBy and aggregateInPlaceBy give you a more specific result than collect because they always return a Map. Using Collectors2 can be helpful if you want to iterate over a Stream and get a primitive map result easily using collect.

Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.

Written by

Java Champion. Creator of the Eclipse Collections OSS Java library (http://www.eclipse.org/collections/). Inspired by Smalltalk. Opinions are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store