Lambda 정리(1)

김도형·2022년 12월 11일
0
post-thumbnail

목차

  • 람다식이란?
  • 람다식 작성
  • 함수형 인터페이스 타입의 매겨변수와 반환타입
  • 람다식의 타입과 형변환
  • 외부 변수를 참조하는 람다식

람다식이란?

람다식 : 메서드를 하나의 식으로 표현한 것 또는 '익명함수'

람다식 작성

  • 메서드 이름, 반환타입 제거
  • {} 대신 -> 사용

함수형 인터페이스 타입의 매개변수와 반환타입

  • 람다식은 익명 클래스의 객체 동등
  • 람다식의 참조변수 타입은 클래스 또는 인터페이스 가능
  • 익명 객체를 람다식으로 대체
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
        Collections.sort(list1, new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                return s2.compareTo(s1);
            }
        });
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
        Collections.sort(list2, (s1, s2) -> s2.compareTo(s1));
static MyFunction2 getMyFunction() { // 반환 타입이 MyFunction2인 메서드
        MyFunction2 f = () -> System.out.println("f3.run()");
        return f; // 또는 return System.out.println("f3.run()"); 사용 가능

람다식의 타입과 형변환

  • 람다식 타입이 함수형 인터페이스의 타입과 일치하는 것은 아님
  • 람다식은 익명 객체이고 익명 객체는 타입이 없음
  • 정확히는 타입은 있지만, 컴파일러가 임의로 이름 정하기 때문에 알 수 없는 것
  • 람다식은 함수형 인터페이스로 형변환 가능, 그리고 형변환은 생략 가능함.
MyFunction f = (MyFunction)( () -> {} );
MyFunction f = ( () -> {} );
  • 람다식은 Object 타입으로 형변환 불가. 오직 함수형 인터페이스만 형변환 가능
  • Object 타입으로 형변환 하려면, 함수형 인터페이스 형변환 후 가능
Object obj = (Object)(MyFunction) (() -> {});
  • 컴파일러 시, 람다식의 타입의 형식은 외부클래스이름$LambdaLambda번호

외부 변수를 참조하는 람다식

  • 람다식도 익명객체, 즉 익명 클래스의 인스턴스이므로 람다식에서 외부에 선언된 변수에 접근하는 규칙은 앞서 익명 클래스에서 배운 것과 동일
@FunctionalInterface
interface MyFunction {
    void myMethod();
}

class Outer {
    int val = 10; // Outer.this.val

    class Inner {
        int val = 20; // this.val

        void method(int i) { // void method(final int i)
            int val = 30; // final int val = 30;
//            i = 10; // 에러. 상수의 값을 변경할 수 없음.

            MyFunction f = () -> {
                System.out.println("i = " + i);
                System.out.println("val = " + val);
                System.out.println("this.val = " + this.val);
                System.out.println("Outer.this.val = " + Outer.this.val);
            };


            f.myMethod();
        }
    } // Inner 클래스의 끝
} // Outer 클래스의 끝

class LamdaEx3 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.method(100);
    }
}

[결과]

i = 100
val = 30
this.val = 20
Outer.this.val = 10
  • 람다식 내에서 참조하는 지역변수는 final 붙지 않아도 상수
  • 람다식 내에서 지역변수 i와 val을 참조하고 있으므로, 람다식 내에서나 다른 어느 곳에서도 해당 변수들은 값 변경 불가
  • 반면 Inner, Outer 클래스의 인스턴스 변수는 상수 간주하지 않아 변경 가능
  • 외부 지역변수와 같은 이름의 람다식 매개변수는 허용되지 않음.

[출처 : 저자 남궁성의 Java의 정석 3rd Edition]

profile
3년간 웹/앱, 자동제어 QA 🔜 개발자로 전향하여 현재 교육 회사에서 백엔드 개발자로 근무 중입니다.(LinkedIn : https://www.linkedin.com/in/dohyoung-kim-5ab09214b)

0개의 댓글