Use a wrapper

Any kind of wrapper is good.

With Java 10+, use this construct as it's very easy to setup:

var wrapper = new Object(){ int ordinal = 0; };
list.forEach(s -> {
  s.setOrdinal(wrapper.ordinal++);
});

With Java 8+, use either an AtomicInteger:

AtomicInteger ordinal = new AtomicInteger(0);
list.forEach(s -> {
  s.setOrdinal(ordinal.getAndIncrement());
});

... or an array:

int[] ordinal = { 0 };
list.forEach(s -> {
  s.setOrdinal(ordinal[0]++);
});

Note: be very careful if you use a parallel stream. You might not end up with the expected result. Other solutions like Stuart's might be more adapted for those cases.

For types other than int

Of course, this is still valid for types other than int.

For instance, with Java 10+:

var wrapper = new Object(){ String value = ""; };
list.forEach(s->{
  wrapper.value += "blah";
});

Or if you're stuck with Java 8 or 9, use the same kind of construct as we did above, but with an AtomicReference...

AtomicReference<String> value = new AtomicReference<>("");
list.forEach(s -> {
  value.set(value.get() + s);
});

... or an array:

String[] value = { "" };
list.forEach(s-> {
  value[0] += s;
});
Answer from Olivier Grégoire on Stack Overflow
Top answer
1 of 10
325

Use a wrapper

Any kind of wrapper is good.

With Java 10+, use this construct as it's very easy to setup:

var wrapper = new Object(){ int ordinal = 0; };
list.forEach(s -> {
  s.setOrdinal(wrapper.ordinal++);
});

With Java 8+, use either an AtomicInteger:

AtomicInteger ordinal = new AtomicInteger(0);
list.forEach(s -> {
  s.setOrdinal(ordinal.getAndIncrement());
});

... or an array:

int[] ordinal = { 0 };
list.forEach(s -> {
  s.setOrdinal(ordinal[0]++);
});

Note: be very careful if you use a parallel stream. You might not end up with the expected result. Other solutions like Stuart's might be more adapted for those cases.

For types other than int

Of course, this is still valid for types other than int.

For instance, with Java 10+:

var wrapper = new Object(){ String value = ""; };
list.forEach(s->{
  wrapper.value += "blah";
});

Or if you're stuck with Java 8 or 9, use the same kind of construct as we did above, but with an AtomicReference...

AtomicReference<String> value = new AtomicReference<>("");
list.forEach(s -> {
  value.set(value.get() + s);
});

... or an array:

String[] value = { "" };
list.forEach(s-> {
  value[0] += s;
});
2 of 10
26

This is fairly close to an XY problem. That is, the question being asked is essentially how to mutate a captured local variable from a lambda. But the actual task at hand is how to number the elements of a list.

In my experience, upward of 80% of the time there is a question of how to mutate a captured local from within a lambda, there's a better way to proceed. Usually this involves reduction, but in this case the technique of running a stream over the list indexes applies well:

IntStream.range(0, list.size())
         .forEach(i -> list.get(i).setOrdinal(i));
🌐
Baeldung
baeldung.com › home › java › java local variable syntax for lambda parameters
Java Local Variable Syntax for Lambda Parameters | Baeldung
January 8, 2024 - The local variable syntax for lambda parameters is the only language feature introduced in Java 11. In this tutorial, we’ll explore and use this new feature. One of the key features introduced in Java 10 was local variable type inference. It allowed the use of var as the type of the local variable instead of the actual type. The compiler inferred the type based on the value assigned to ...
Discussions

java - Lambdas: local variables need final, instance variables don't - Stack Overflow
Find centralized, trusted content ... you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... In a lambda, local variables need to be final, but instance variables don't. Why so? ... Let be known that at least with the latest version of the compiler java 1.8 local ... More on stackoverflow.com
🌐 stackoverflow.com
Why can't lambda expressions access local or non static variables?
Unless the quote from the mooc makes more sense in context, it's completely misleading. The only thing you can't access from lambdas are local variables that are not effectively final. You very much can access: The current object this Effectively final local variables (i.e. variables that aren't re-assigned within the method). Fields of any object that you can access (both static and non-static) So if you want to change the value of a local variable from within a lambda, a common workaround is to wrap the value in an object (or one-element array) and then re-assign the field of the object rather than the local variable itself. To modify a non-static field, no workaround is needed. That just works. And the reason why you can't modify local variables from lambdas is that lambdas can outlive the method that created them and the Java designers didn't want to add mutable closures to the language. More on reddit.com
🌐 r/learnjava
3
11
June 21, 2023
Java 11: Local-Variable Syntax for Lambda Parameters - applications - Stack Overflow
Find centralized, trusted content ... you use most. Learn more about Collectives ... Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams ... I am curious about Java-11 in general, but specifically JEP:323 which plans to add the var declaration to Lambda operation variables... More on stackoverflow.com
🌐 stackoverflow.com
java - Set a local variable value from inside a lambda - Stack Overflow
Possible duplicate of Local variable log defined in an enclosing scope must be final or effectively final ... Create an class to have this attribute, so the object from it will be final, but not the instance variables · Make the variable class scope (be careful with multithreading) These solutions work, but maybe it's not the best option, so to have some inspiration see: Lambdas... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Medium
codesnoob.medium.com › java-8-local-variables-and-lambda-function-4ce96f80c97a
Java 8 — Local Variables and Lambda Function - Sreenidhi KV
June 10, 2022 - How to manipulate the local variables of a method, that get’s consumed by Lambda function? Can use Atomic References eg, AtomicIntegers which ensures concurrency. Although we shouldn’t be manipulating local variables inside lambdas.
🌐
YouTube
youtube.com › codeedx
Capturing Local Variables in Lambda Expressions | Java Lambda Expressions #6 - YouTube
In this video, we will learn about Capturing Local Variables in Lambda Expressions. Important Notes: Lambda expressions can use variables defined in an outer...
Published   November 26, 2021
Views   1K
🌐
TutorialsPoint
tutorialspoint.com › what-are-the-rules-for-a-local-variable-in-lambda-expression-in-java
What are the rules for a local variable in lambda expression in Java?
July 11, 2020 - Inside lambda expression, we can't assign any value to some local variable declared outside the lambda expression. Because the local variables declared outside the lambda expression can be final or effectively final.
Top answer
1 of 10
67

The fundamental difference between a field and a local variable is that the local variable is copied when JVM creates a lambda instance. On the other hand, fields can be changed freely, because the changes to them are propagated to the outside class instance as well (their scope is the whole outside class, as Boris pointed out below).

The easiest way of thinking about anonymous classes, closures and labmdas is from the variable scope perspective; imagine a copy constructor added for all local variables you pass to a closure.

2 of 10
28

In a document of project lambda, State of the Lambda v4, under Section 7. Variable capture, it is mentioned that:

It is our intent to prohibit capture of mutable local variables. The reason is that idioms like this:

int sum = 0;
list.forEach(e -> { sum += e.size(); });

are fundamentally serial; it is quite difficult to write lambda bodies like this that do not have race conditions. Unless we are willing to enforce—preferably at compile time—that such a function cannot escape its capturing thread, this feature may well cause more trouble than it solves.

Another thing to note here is, local variables are passed in the constructor of an inner class when you access them inside your inner class, and this won't work with non-final variable because value of non-final variables can be changed after construction.

While in case of an instance variable, the compiler passes a reference of the object and object reference will be used to access instance variables. So, it is not required in case of instance variables.

PS : It is worth mentioning that anonymous classes can access only final local variables (in Java SE 7), while in Java SE 8 you can access effectively final variables also inside lambda as well as inner classes.

🌐
Baeldung
baeldung.com › home › java › core java › why do local variables used in lambdas have to be final or effectively final?
Why Do We Need Effectively Final? | Baeldung
May 29, 2025 - We refer to these lambdas as capturing lambdas. They can capture static variables, instance variables, and local variables, but only local variables must be final or effectively final.
Find elsewhere
🌐
InformIT
informit.com › articles › article.aspx
3.7 Lambda Expressions and Variable Scope | Java Interfaces and Lambda Expressions | InformIT
The prohibition against mutation only holds for local variables. If count is an instance variable or static variable of an enclosing class, then no error is reported even though the result is just as undefined. ... The counter variable is effectively final—it is never changed since it always refers to the same array, so you can access it in the lambda expression.
🌐
Reddit
reddit.com › r/learnjava › why can't lambda expressions access local or non static variables?
r/learnjava on Reddit: Why can't lambda expressions access local or non static variables?
June 21, 2023 -

Hello fellow java learners,

I am learning java through mooc of University of Helsinki and I am currently learning about streams. It says the following:

"Functions that handle stream elements ​​cannot change values ​​of variables outside of the function. This has to do with how static methods behave - during a method call, there is no access to any variables outside of the method. With functions, the values ​​of variables outside the function can be read, assuming that those values of those variables do not change in the program."

I do not understand why this is the case and how does this correlate to the static functions? Static functions can use for example local variables in main function when it's passed as a parameter. Can anyone eli5? Sorry if this is a stupid question. Thanks in advance!!!!

Top answer
1 of 3
10
Unless the quote from the mooc makes more sense in context, it's completely misleading. The only thing you can't access from lambdas are local variables that are not effectively final. You very much can access: The current object this Effectively final local variables (i.e. variables that aren't re-assigned within the method). Fields of any object that you can access (both static and non-static) So if you want to change the value of a local variable from within a lambda, a common workaround is to wrap the value in an object (or one-element array) and then re-assign the field of the object rather than the local variable itself. To modify a non-static field, no workaround is needed. That just works. And the reason why you can't modify local variables from lambdas is that lambdas can outlive the method that created them and the Java designers didn't want to add mutable closures to the language.
2 of 3
1
On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge. If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options: Limiting your involvement with Reddit, or Temporarily refraining from using Reddit Cancelling your subscription of Reddit Premium as a way to voice your protest. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-lambda-expression-variable-capturing-with-examples
Lambda Expression Variable Capturing with Examples - GeeksforGeeks
October 25, 2025 - Explanation: The lambda directly modifies the static variable counter, since it is shared across all instances of the class. Lambda Expression can capture local variables declared in the enclosing method.
🌐
Javaprogramto
javaprogramto.com › 2019 › 07 › lambda-accessing-Variable.html
Java 8: Accessing Variables from Lambda Expressions JavaProgramTo.com
August 1, 2019 - Note: If we try to change the value ... to declare a variable as an effective final. Enclosed variables can be used at any place in Lambda but the value can not be changed....
🌐
Codementor
codementor.io › community › variable used in lambda expression should be final or effectively final
Variable used in Lambda Expression Should be Final or Effectively Final | Codementor
June 29, 2022 - Streams allow Lambda Functions ... might result in an incorrect value. local values are saved in stack, each thread has its own call stack, and no thread can access other thread stack · package org.wesome.java8; import ...
🌐
Incus Data
incusdata.com › home › local variable syntax for lambda parameters
Local Variable Syntax For Lambda Parameters • 2026 • Incus Data Programming Courses
June 3, 2022 - For consistency with using var for local variable type inference, we can now use var for the formal parameters of an implicitly typed lambda expression: Comparator<String> comp3 = (var first, var second) -> second.length() - first.length(); It’s a personal choice as to whether we want to use var in this situation because the type inferred for the implicitly typed parameter (i.e.
🌐
CodingTechRoom
codingtechroom.com › question › how-to-modify-local-variables-inside-a-lambda-expression-in-java
How to Modify Local Variables Inside a Lambda Expression in Java - CodingTechRoom
In Java, local variables referenced from a lambda expression must be effectively final. This means that you cannot modify local variables like 'ordinal' after it's been established. To work around this limitation, you can use an array or a mutable wrapper class.
🌐
Oracle
docs.oracle.com › javase › tutorial › java › javaOO › lambdaexpressions.html
Lambda Expressions (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
Consequently, you can directly access fields, methods, and local variables of the enclosing scope. For example, the lambda expression directly accesses the parameter x of the method methodInFirstLevel. To access variables in the enclosing class, use the keyword this.
🌐
w3tutorials
w3tutorials.net › blog › modifying-local-variable-from-inside-lambda
How to Modify Local Variables Inside a Lambda in Java: Fixing the Compile Error — w3tutorials.net
This blog dives deep into why this error occurs, what “effectively final” means, and provides actionable solutions to modify local variables within lambdas. By the end, you’ll understand the underlying mechanics and confidently choose the best approach for your code. ... Let’s start with a simple example that triggers the error. Suppose you want to count the number of elements in a list that meet a condition using a lambda: import java.util.Arrays; import java.util.List; public class LambdaLocalVariableExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); int count = 0; // Local variable names.forEach(name -> { if (name.length() > 4) { count++; // Compile Error: "local variables referenced from a lambda expression must be final or effectively final" } }); System.out.println("Count: " + count); } }
🌐
InformIT
informit.com › articles › article.aspx
3.7 Lambda Expressions and Variable Scope | Interfaces and Lambda Expressions in Java | InformIT
The prohibition against mutation only holds for local variables. If count is an instance variable or static variable of an enclosing class, then no error is reported even though the result is just as undefined. ... The counter variable is effectively final—it is never changed since it always refers to the same array, so you can access it in the lambda expression.
🌐
Oracle
docs.oracle.com › en › java › javase › 13 › language › local-variable-type-inference.html
Oracle : Local Variable Type Inference
Index variables declared in traditional for loops: for (var counter = 0; counter < 10; counter++) {...} // infers int ... Formal parameter declarations of implicitly typed lambda expressions: A lambda expression whose formal parameters have inferred types is implicitly typed: