1

I am looping through a LinkedHashMap and incrementing i counter and below is how I used to do it using a for-loop.

int i = 0;

for (Map.Entry<String, String> entry : linkedHashMap.entrySet()) {
      Car car = new Car();

      car.setCarId(String.valueOf(i++));
      car.setCarName(entry.getKey());
      car.setOdometerReading(entry.getValue());

      appRoomRepository.insertCarDetails(car);
}

Below is how I want to use a foreach-loop

int i = 0;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
     linkedHashMap.forEach((key, value) -> {
           Car car = new Car();

           car.setCarId(String.valueOf(i++));
           car.setCarName(key);
           car.setOdometerReading(value);

           appRoomRepository.insertCarDetails(car);
        });
}

I am stuck in this line car.setCarId(String.valueOf(i++));

I keep getting this error "Variable used in lambda expression should be final or effectively final". How can I increment counter i?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Emmanuel Njorodongo
  • 1,004
  • 17
  • 35
  • 1
    Does this answer your question? [Variable used in lambda expression should be final or effectively final](https://stackoverflow.com/questions/34865383/variable-used-in-lambda-expression-should-be-final-or-effectively-final) – zysaaa Nov 25 '21 at 09:46

2 Answers2

2

Lambda expressions can use variables defined in an outer scope They can capture static variables, instance variables, and local variables, but only local variables must be final or effectively final

Use AtomicInteger:

AtomicInteger i = new AtomicInteger(0);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

     linkedHashMap.forEach((key, value) -> {

           Car car = new Car();

           car.setCarId(String.valueOf(i.getAndIncrement()));
           car.setCarName(entry.getKey());
           car.setOdometerReading(entry.getValue());

           appRoomRepository.insertCarDetails(car);

        });
}

```
Metin Bulak
  • 537
  • 4
  • 8
  • 30
0

Couple of options:

You could iterate with a range

IntStream.range(0, 10).forEach(n ->...

Or you could use an AtomicInteger and name that 'final'

Variable used in lambda expression should be final or effectively final this post has a good discussion of why this needs to happen.