Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should variables inside a forEach loop not be changed?

Tags:

lambda

java-8

I am iterating a list in Java 7 loop and Java 8 forEach loop. The Java 8 loop wants the variables inside it to not change. For example:

List<String> testList = Arrays.asList( "apple", "banana", "cat", "dog" ); int count = 0;  testList.forEach(test -> {   count++; // Compilation error: Local variable count defined in an enclosing scope must be final or effectively final });  for (String test : testList) {   count++; // Code runs fine } 

Can someone explain why? Is it a drawback of Java 8?

like image 366
schoolcoder Avatar asked Aug 04 '15 05:08

schoolcoder


People also ask

Can you change a foreach loop?

Why C#'s foreach loop cannot change what it loops over. With a foreach loop we easily iterate over all elements in a collection. During each pass through the loop, the loop variable is set to an element from a collection.

What can foreach loops not be used for?

For-each cannot be used to initialize any array or Collection, because it loops over the current contents of the array or Collection, giving you each value one at a time. The variable in a for-each is not a proxy for an array or Collection reference.

Can we increment a variable inside foreach lambda?

Let's say, we have a list of integers and we want to know the number of integers that are greater than 50 using a forEach loop and lambda expression. We can not declare an integer variable and increment it inside the loop after checking the color or each ball since it will be an error.

What is difference between regular for loop and foreach loop?

The biggest differences are that a foreach loop processes an instance of each element in a collection in turn, while a for loop can work with any data and is not restricted to collection elements alone. This means that a for loop can modify a collection - which is illegal and will cause an error in a foreach loop.


1 Answers

The Java Memory Model has very important property: it guarantees that local variables and method parameters are never writable by another thread. This adds much safety to multi-threading programming. However when you create a lambda (or an anonymous class), nobody knows how it will be used. It can be passed to another thread for execution (for example, if you use parallelStream().forEach(...)). Were it possible to modify the local variable that important property would be violated. Not the thing the Java language developers would sacrifice.

Usually when you are using lambdas, you are trying to program in functional way. But in functional programming mutable variables are considered bad practice: it's better to assign every variable only once. So trying to modify the local variable actually smells. Use various stream reduction methods instead of forEach to produce a good functional code.

like image 167
Tagir Valeev Avatar answered Sep 20 '22 23:09

Tagir Valeev