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

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

effectively final :

  • A variable or parameter whose value is never changed after it is initialized
  • If a reference is not changed it is effectively final even if the object referenced is changed.
  • Any variable that is assigned once and only once, is โ€œeffectively finalโ€.

In simple terms :

Imagine adding the final modifier to a variable declaration. If, with this change, the program continues to behave in the same way, both at compile time and at run time, then that variable is effectively final.

It looks like it is exact similar way. But only difference is no final keyword.

eg :

these are final

final int variable = 123;

final int number;
number = 23;

this is effective final

int variable = 123;

int number;
number = 34;

Fruther discussion :

Variables inside anonymous class must be final in outer class

#effectively-final, #final, #lambda

Iterating Collections (Map / List) using Lambda

  1. Classical way of iterating a map

Syntax :

for(Map.Entry entry : map.entrySet){
    entry.getKey()
    entry.getValue()

example :

private static void oldMapIter(Map map) {
	for(Map.Entry entry : map.entrySet()) {
		System.out.println(entry.getKey() + ":" + entry.getValue());
	}
}

We can simply use Lambda expressions to get this done.

private static void newMapIter(Map map) {
	// map.forEach((k,v)->System.out.println("newMapIter()."+k+" : " + v ));
	map.forEach((k,v)->{
		System.out.println(k+" : "+v );
	});
}

2. Classical way of iterating a map

private static void oldCollection(List list) {
	for (String string : list) {
		System.out.println(string);
	}
}

Iterate using Lambda expression :

private static void newCollection(List list) {
	// list.forEach(item -> System.out.println("newCollection().item : " + item));
	list.forEach(item -> {
		System.out.println(item);
	});
}

But there are some downsides of using Lambda in forEach. One of them is restrictions to use variables inside the block. Because to mutate (increase the index etc) a variable inside the Lambda forEach block, it should be final or effectively final.


Further readiings :

  1. Passing a variable (an int or some immutable type) to a lambda block
  2. Local variables referenced from a lambda expression must be final or effectively final

#collection, #effectively-final, #final, #iteration, #lambda, #list, #map