ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 람다식 표현 (Lambda Expression)
    언어/Java 2021. 4. 4. 00:04

    자바 8에서 도입된 개념으로 함수를 변수처럼 사용하는 사용하는 개념입니다. 함수를 변수처럼 사용하므로 파라미터로 다른 메소드에 전달할 수도 있고 반환값으로 함수를 받을 수 있습니다. 자바에서 람다식은 다른 스크립트 언어처럼 완전한 함수형 프로그래밍 방식은 아닙니다. 인터페이스 형식을 빌려서 람다식을 표현하기 때문에 함수형 프로그래밍의 장점을 완벽하게 가지지 못합니다. 장단점은 아래에서 설명합니다.

    사용법

    (매개변수1, 매개변수2, ...) -> {실행문...}

    매개변수의 이름은 자유롭게 정할 수 있고 타입을 명시하지 않아도 됩니다. -> 는 실행문에서 좌변에 설정한 값들을 보내 사용한다 라고 이해하면 쉽습니다.

    예시

    예시를 하기 위해 사전에 아래와 같은 코드가 작성되어 있다고 가정합니다.

    @FunctionalInterface
    public interface Calc {
        int plus(int x, int y);
    }
    
    public class MyClass {
        public int test(Calc calc) {
            int number = calc.plus(1, 2);
            System.out.println("plus is "+number);
            return number;
        }
    }

    먼저 자바 람다식을 사용하지 않은 예제입니다.

    public class Main {
        public static void main(String[] args) {
            MyClass myClass = new MyClass();
            var sum = myClass.test(new Calc() {
                @Override
                public int plus(int x, int y) {
                    System.out.println("x: " + x + " y: " + y);
                    return x + y;
                }
            });
    
            System.out.println();
        }
    }
    
    x: 1 y: 2
    plus is 3
    3

    여기서 @FunctionalInterface는 구현해야 할 추상 메소드가 1개만 정의된 인터페이스를 가리킵니다. 만약 두 개 이상 지정할 경우 컴파일러에서 에러를 발생시킵니다.

    아래는 람다식을 사용한 예제입니다.

    public class Main {
    
        public static void main(String[] args) {
            MyClass myClass = new MyClass();
            var sum = myClass.test((x, y) -> {
                System.out.println("x: " + x + " y: " + y);
                return x + y;
            });
    
            System.out.println(sum);
        }
    }
    
    x: 1 y: 2
    plus is 3
    3

    아래 예시를 통해 호출이 어떤 순서로 되는지 다시 확인해 봅니다.

    public class Main {
        public static void exec(Calc calc) {
            int x = 1; // 2
            int y = 2; // 3
            int value = calc.plus(x, y); // 4 실행을 위해 아래 선언부로 이동. 6. 5에서 1 + 2 = 3 이라는 결과 받음
            System.out.println(value); // 7 출력
        }
    
        public static void main(String[] args) {
            exec((i, j)->{ // 1. 호출되면 exec로 이동
                return i+j; // 5. 여기서 i는 위의 x, j는 y이므로 1+2 표현이 됨. 결과를 위로 반환
            });
        }
    }

    위의 예제 같은 경우 아래와 같이 더 간결하게 표현할 수 있습니다.

    public static void main(String[] args) {
            exec(Integer::sum);
        }

    장점

    자바 8 이전의 익명 클래스에 비해 코드가 간결해짐

    람다식에 개발자의 의도를 명확하게 표현할 수 있음

    병렬 프로그래밍에 용이

    단점

    람다식을 남용하면 비슷한 함수가 중복 생성될 수 있음

    재귀함수로 만들기가 까다로움

    댓글