[ジャワ]ランダスクリーンショット


学習の背景

    public int getBestScore() {
        int sum = 0;

        cardHand.stream()
                .map(Card::getNumber)
                .map(Number::getScore)
                .map(number -> {
                    if (sum > 21) {
                        // Ace가 있는지 탐색해서 ace가 있으면 1로 계산하기
                    }
                })
                .reduce(0, Integer::sum);


        return sum;
    }
合計が21を超えるとaceがあるかどうかを試して、11の代わりに1でaceを計算したいと思います.
しかし、次のような文が出てきました.
Variable used in lambda expression should be final or effectively final

コンセプト


ランダキャプチャは、ランダの外部で定義された変数がランダ式の内部で使用されます.しかし、制約条件がある.
インスタンス変数と静的変数はramdaで自由に参照できますが、領域変数はそうではありません.領域変数はfinal変数または実質的にfinalのように使用(すなわち再割り当ては発生しない)する変数のみを使用できます.

どうしてこんなことになったの?


違いはどこに格納されているかです.インスタンス変数はhipに格納され、領域変数はスタックに格納されます.領域変数はスレッド間で共有されないため、コピーが使用されます.したがって、レプリカの値は変更できないため、値の再割り当ては許可されません.
これらの制約変数は、外部変数を変更する従来のコマンドプログラミングとは異なります.

解決する

    public int getBestScore() {
        int sum = cardHand.stream()
                .map(Card::getNumber)
                .mapToInt(Number::getScore)
                .sum();

        for (Card card : cardHand) {
            sum = card.getBest(sum);
        }

        return sum;
    }

リファレンス


モダンジャワアクション3枚
https://bugoverdose.github.io/development/lambda-capturing-and-free-variable/