effectively final

// 빈도가 가장 높은 recommend_Gif 찾기
        String mostFrequentGif = Collections.max(gifFrequencyMap.entrySet(), Map.Entry.comparingByValue()).getKey();

        // 가장 높은 빈도의 recommend_Gif가 여러 개인 경우 랜덤 선택
        List<String> mostFrequentGifs = gifFrequencyMap.entrySet().stream()
                .filter(entry -> entry.getValue().equals(gifFrequencyMap.get(mostFrequentGif))) // 여기서 오류나옴 
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

람다 표현식 내에사 사용할 때,

람다 표현식 내에서는 final 또는 effectively final로 만들어야 한다.

그래서 mostFrequentGif를 effectively final로 만들어주기 위해서 currentGif 라는 새로운 변수 넣기

String mostFrequentGif = Collections.max(gifFrequencyMap.entrySet(), Map.Entry.comparingByValue()).getKey();

List<String> mostFrequentGifs = gifFrequencyMap.entrySet().stream()
        .filter(entry -> {
            String currentGif = mostFrequentGif; // effectively final 변수
            return entry.getValue().equals(gifFrequencyMap.get(currentGif));
        })
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());

effectively final 변수 만드는법

effectively final

effectively final은 람다 표현식이 등장한 자바 8에 함께 등장했습니다. 이는 final 키워드가 선언되지 않았지만, 값이 재할당되지 않아 final 변수와 유사하게 동작하는 변수를 의미합니다.

자바 언어 스펙을 살펴보면 아래와 같은 경우를 effectively final로 간주합니다.

객체의 경우라면, 해당 객체가 가리키는 참조를 변경하지 않으면 effectively final로 간주합니다.

그렇다면 왜 이러한 특징을 가지는 변수를 람다 표현식 내부에서 사용해야 하는지에 대해 알아보겠습니다.

람다 표현식에서 사용하는 변수