Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local variable i defined in an enclosing scope must be final or effectively final

I want to implement this endpoint with internal search:

@PostMapping("terminals_risk_filter/change_order/{terminalId}")
    public ResponseEntity<?> updateFiltersPositions(@PathVariable Integer terminalId,
            @RequestBody List<ChangeOrderRiskFiltersDTO> newFiltersPositionsList) {

        List<RiskFilters> filterList = riskFilterService.findRiskFiltersByTerminalId(terminalId);

        for (int i = 0; i < newFiltersPositionsList.size(); i++) {
//          RiskFilters filter = filterList.findById(newFiltersPositionsList.get(i).getId());

            Optional<RiskFilters> filter_payload = filterList.stream().filter(f -> newFiltersPositionsList.get(i).getId() == f.getId()).findAny();
            RiskFilters filter = filter_payload.get();      

            filter.setPosition(newFiltersPositionsList.get(i).getPosition());
            riskFilterService.save(filter);
        }
        return ok().build();
    }

But I get error message Local variable i defined in an enclosing scope must be final or effectively final Can you give me some advice how I can fix this issue, please? For example can I skip the for cycle and use maybe stream into stream?

like image 438
Peter Penzov Avatar asked Jun 13 '19 15:06

Peter Penzov


People also ask

What is enclosing scope in Java?

Since it is a rule in Java programming language that variable in an enclosing scope can't be change in inner class or lambda expression, so you can't change the value of the variable.

How resolve variable used in lambda expression should be final or effectively Final?

The local variables that a lambda expression may use are referred to as “effectively final”. An effectively final variable is one whose value doesn't change after it's first assigned. There is no need to explicitly declare such a variable as final, although doing so would not be an error.

Can we use Non final variable in lambda?

A non-final local variable or method parameter whose value is never changed after initialization is known as effectively final. It's very useful in the context of the lambda expression. If you remember, prior to Java 8, we cannot use a non-final local variable in an anonymous class.


2 Answers

Can you give me some advice how I can fix this issue, please?

Why does this happen? You can read about it here: Lambdas: local variables need final, instance variables don't

Minimal changes to solve your problem: Don't use the i variable itself. Create a copy of it and make it final.

final int iCopy = i;
Optional<RiskFilters> filter_payload = filterList.stream().filter(f -> newFiltersPositionsList.get(iCopy).getId() == f.getId()).findAny();

For example can I skip the for cycle and use maybe stream into stream?

You could give it a try:

// replace the for-loop

// or just.... `newFiltersPositionsList.forEach(/* ... */)`
newFiltersPositionsList.stream().forEach(filterPosition -> {
    Optional<RiskFilters> filter_payload = filterList.stream()
            .filter(f -> filterPosition.getId() == f.getId())
            .findAny();
    RiskFilters filter = filter_payload.get();

    filter.setPosition(filterPosition.getPosition());
    riskFilterService.save(filter);
});

Also, you could use a for-each instead of a for-loop:

for (ChangeOrderRiskFiltersDTO filterPosition : newFiltersPositionsList) {
    Optional<RiskFilters> filter_payload = filterList.stream()
           .filter(f -> filterPosition.getId() == f.getId())
           .findAny();
    RiskFilters filter = filter_payload.get();
    filter.setPosition(filterPosition.getPosition());
    riskFilterService.save(filter);
}
like image 58
lealceldeiro Avatar answered Sep 29 '22 21:09

lealceldeiro


You can do it like below as well.

final ChangeOrderRiskFiltersDTO dto = newFiltersPositionsList.get(i);
Optional<RiskFilters> filter_payload = filterList.stream().filter(f -> dto.getId() == f.getId()).findAny();
if(filter_payload.isPresent()){
  RiskFilters filter = filter_payload.get();
  //More operations
}
like image 43
Manish Bansal Avatar answered Sep 29 '22 19:09

Manish Bansal