Skip to content
Advertisement

Accumulator Generator test – Java 8

Paul Graham, in his great article Revenge of the Nerds, claimed that languages vary in power. He mentioned a nice exercise – writing an accumulator generator:

We want to write a function that generates accumulators– a function that takes a number n, and returns a function that takes another number i and returns n incremented by i.

Solution in Java is

JavaScript

I am curious, whether in Java 8 (thanks to lambda) is already some elegant way how to write it similarly to Groovy, see below. I tried Function<Integer, Integer>

But I stuck with this compiler error.

local variables referenced from a lambda expression must be final or effectively final

So do you have some Java 8 solution?

Compare the old Java solution with the Groovy one

JavaScript

Advertisement

Answer

First of all, you can still use all the new Java 8 interfaces using anonymous class syntax instead of lambda syntax. For example:

JavaScript

(Rather than Function, I used IntUnaryOperator here as it allows the use of primitive ints instead of boxed Integers. It’s logically equivalent to Function<int,int>, if that were legal.)

Now, how can we shorten this bulky thing with lambda syntax? Local variables passed into lambdas are required to be (effectively) final. The limitation means you cannot trivially write a variable whose value accumulates between calls. The following does not work:

JavaScript

We can work around the limitation by using some mutable object as a holder for the current accumulator value. A one-element array can be used for this. The array variable is not changing – only the contents of the array object it points at are changing, so the array variable is effectively final and this is allowed:

JavaScript

Any object with a mutable field can potentially be used as a holder. As suggested below by @andersschuller, an AtomicInteger fits well here, and makes the returned functions thread-safe:

JavaScript

And @srborlongan points out this can be re-written using a method reference, which is even shorter (though not more readable):

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement