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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With