我在封闭范围内定义的局部变量必须是final或有效的final

时间:2019-06-13 15:02:36

标签: java for-loop java-8 java-stream

我想通过内部搜索实现此端点:

@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();
    }

但是我收到错误消息Local variable i defined in an enclosing scope must be final or effectively final,能否请您给我一些建议,以解决此问题?例如,我可以跳过for周期并使用流到流吗?

3 个答案:

答案 0 :(得分:5)

  

能否请教我一些如何解决此问题的建议?

为什么会这样?您可以在这里阅读有关内容:Lambdas: local variables need final, instance variables don't

为解决您的问题而进行的最小更改:请勿使用i变量本身。创建它的副本并使其final

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

例如,我可以跳过for循环并使用流到流吗?

您可以尝试一下:

// 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);
});

此外,您可以使用 for-each 代替 for循环

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);
}

答案 1 :(得分:2)

您也可以像下面一样进行操作。

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
}

答案 2 :(得分:2)

如果要避免添加i的最终副本的简单解决方案,则可以提取实际的“最终”信息:

final int id = newFiltersPositionsList.get(i).getId()

您的lambda可以变成:

f -> id == f.getId()