JaPark Bug World

[JAVA] 함수형 인터페이스와 람다 - 람다 표현식 본문

개발새발/더 자바, Java 8

[JAVA] 함수형 인터페이스와 람다 - 람다 표현식

JAstory 2024. 3. 31. 19:32

람다 표현식

 

람다

  • (인자 리스트) -> {바디}

인자 리스트

  • 인자가 없을 때 : ()
  • 인자가 한개일 때 : (one) 또는 one
  • 인자가 여러개 일 때 : (one, two)
  • 인자의 타입은 생략 가능, 컴파일러가 추론(infer)하지만 명시 가능, (integer one, integer two) 
// 인자가 없을 시 
Supplier<Integer> getTen = () -> 10;

// 인자가 한개 일 시
Function<Integer, Integer> oneParam = (i) -> i;

// 인자가 여러개 일 때
BiFunction<Integer, Integer, Integer> biFunc = (integer, integer2) -> integer + integer2;

바디

  • 화살표 오른쪽에 함수 본문을 정의한다.
  • 여러 줄인 경우에 {}를 사용해서 묶는다
  • 한 줄인 경우에 생략 가능, return도 생략 가능
BinaryOperator<Integer> biFunc = (integer, integer2) -> {
	// 두줄이상이면 {} 사용
    return integer + integer2; 
};

// 한줄인 경우에는 생략 가능
BinaryOperator<Integer> biFunc = (integer, integer2) -> integer + integer2;

변수 캡처 (Variable Capture)

  • 로컬 변수 캡처
    • final이거나 effective final인 경우에만 참조할 수 있다.
    • 그렇지 않을 경우 concurrency 문제가 생길 수 있어 컴파일러가 방지한다
  • effective final
    • 이것도 역시 자바 8부터 지원하는 기능으로 사실상 final 변수
    • final 키워드 사용하지 않은 변수를 익명 클래스 구현체 또는 람다에서 참조할 수 있다.
  • 익명 클래스 구현체와 달리 쉐도윙 하지 않는다.
    • 익명 클래스는 새로 스콥을 만들지만, 람다는 람다를 감싸고 있는 스콥과 같다.
private void run() {
    // 자바8부터는 final 생략 가능
    int baseNum = 10;

    // 로컬 클래스, 쉐도잉 가능
    class LocalClass {
        void printBaseNum() {
            int baseNum = 11;
            // printBaseNum 함수 안에 선언한 baseNum으로 인식
            System.out.println(baseNum); 
        }
    }

    // 익명 클래스, 쉐도잉 가능
    Consumer<Integer> integerConsumer = new Consumer<Integer>() {
        @Override
        public void accept(Integer baseNum) {
            // aceept에서 넘어오는 인자값으로 인식
            System.out.println(baseNum);
        }
    };

    // 람다, 쉐도잉 불가능
    IntConsumer printInt = (baseNum) -> {
        // System.out.println에 선언된 baseNum에서 error 발생
        System.out.println(baseNum);
    };
    printInt.accept(10);
}

람다에서 선언한 baseNum은 run() 함수안에 선언한 baseNum과 같은 scope여서 쉐도잉이 되지 않음.


인프런 더 자바, Java8 백기선님 강의를 참고하여 정리한 내용입니다.