Skip to content

Getting local variable defined in the enclosing scope must be final or effective final

I am getting “local variable defined in the enclosing scope must be final or effective final” as highlighted below. I am not sure how to fix this out in lambda expression.

enter image description here

synchronizationVBOVO.getProductVO().getProducts().forEach(eachProduct -> {
        Products product = v1UserIdaasEntitlementRequest.new Products();
        product.setName(eachProduct.getProductName());
        Product entitleProduct = entitlementResponse.getProducts().stream()
                .filter(entitleproduct -> entitleproduct.getName().equalsIgnoreCase(eachProduct.getProductName()))
                .findAny().orElse(null);
        List<Packages> packages = new ArrayList<>();
        Packages pack = v1UserIdaasEntitlementRequest.new Packages();
        eachProduct.getPackages().forEach(productPack -> {
            pack.setName(productPack.getPack().getPackageName());
            Package entitlePackage = new Package();
            if(null != entitleProduct && null != entitleProduct.getPackages() && !entitleProduct.getPackages().isEmpty()) {
                 entitlePackage =  entitleProduct.getPackages().stream().filter(
                    entitlePack -> 
                        entitlePack.getName().equalsIgnoreCase(productPack.getPack().getPackageName()))
                    .findAny().orElse(null);
            }
            List<RumLimits> rumLimits = new ArrayList<>();
            RumLimits rumlimit = v1UserIdaasEntitlementRequest.new RumLimits();
            productPack.getPack().getRumLimits().forEach(rumLimit -> {
                setRumLimits(entitlePackage, rumLimits, rumlimit, rumLimit);
                Wallet wallet = v1UserIdaasEntitlementRequest.new Wallet();
                setWallet(v1UserIdaasEntitlementRequest, pack, entitlePackage, wallet);
            });
            pack.setRumLimits(rumLimits);
            packages.add(pack);
        });
        product.setPackages(packages);
        allProducts.add(product);
    });

Answer

Try replacing this:

Package entitlePackage = new Package();
if(null != entitleProduct && null != entitleProduct.getPackages() && !entitleProduct.getPackages().isEmpty()) {
                 entitlePackage =  entitleProduct.getPackages().stream().filter(
                    entitlePack -> 
                        entitlePack.getName().equalsIgnoreCase(productPack.getPack().getPackageName()))
                    .findAny().orElse(null);
}

by this:

Package entitlePackage =
        Optional.ofNullable(entitleProduct)
                .map(Product::getPackages)
                .map(Collection::stream)
                .orElse(Stream.empty())
                .filter(e -> productPack.getPack()
                                        .getPackageName()
                                        .equalsIgnoreCase(e.getName()))
                .findAny()
                .orElseGet(Package::new);

The entitlePackage will be effectively final. Also your code will be much easier to read and maintain.