Modifying local variable from inside lambda
Modifying local variables directly within lambda expressions is forbidden as they are required to be effectively final. To alter a value, yet stick to this rule, you can wrap the variable in an array or use a concurrent class such as AtomicInteger
:
This method works since it changes the value, not the immutable reference itself.
Navigate the restrictions
Wrapping variables
Immutable local variables can appear "changeable" in lambdas if encased in a wrapper class. The mutable wrapper gives you a sneaky workaround:
The array trick
An array can play the same trick. Though the array reference stays the same, the values it stores can alter:
You can even craft your own mutable holder to really personalize this approach.
Anonymous power with Java 10+
Java 10 gave us var
. Combine this language feature with anonymous classes to encapsulate mutable state:
Fancy stream-based iteration
By using IntStream.range
, you can mutate elements in a fancy, stream-based approach:
Play safe with parallel streams
When dealing with parallel streams, it's important to be thread-safe. Multiple threads meddling with your variable can result in chaos — like adding too many chefs to a soup:
Reduction: another way out
Rather than mutating local variables, consider reduction techniques. It's like wrangling your results into a single, neat summary:
Are you asking the right question?
Sometimes striving to mutate a local variable within a lambda hints at an XY problem. Looking sideways at the problem might lead to simpler, more elegant solutions.
Thinking outside the sandbox
If AtomicInteger
or AtomicReference
don't suit, it might be worth shielding the mutable state within a mutable class or leverage collectors to sidestep the need to mutate local variables.
Heed those best practices
Remember, lambdas love immutable state, and cleaner, more maintainable code can often be achieved by masterfully avoiding mutations altogether.
Was this article helpful?