람다 표현식 (Lambda Expression)

람다 표현식(Lambda Expression)이란 함수형 프로그래밍을 구성하기 위한 함수식이며, 간단히 말해 자바의 메소드를 간결한 함수식으로 표한한 것이다.

 

지금까지 자바에서는 메소드를 표현하려면 클래스를 정의해야 했다. 하지만 람다식으로 표현하면 메소드의 이름과 반환값을 생략할 수 있고, 이를변수에 넣어 자바 코드가 매우 간결해지는 장점이 있다.

 

아래 그림에서 보듯이  int add(int a, int b) {}  메소드 표현식을, 메서드 타입, 메소드 이름, 매개변수 타입, 중괄호, return 문을 생략하고, 화살표 기호를 넣음으로써 코드를 혁명적으로 함축했음을 볼 수 있다. 이러한 특징으로 람다식을 이름이 없는 함수 익명 함수(anonymous function) 라고도 한다.

타입을 생략을 해도 컴파일러가 에러를 띄우지않는 이유는, 컴파일러 나름대로 생략된 타입 위치를 추론하여 동작하게 해주기 때문이다.

람다식이 처음에는 생소하게 느껴져 오히려 거부감이 들 수 있다. 하지만 문법이 혁신적으로 간결해 지는 것 만큼, 람다식에 익숙해지면 가독성 면에서 큰 장점을 얻게 된다. 특히 컬렉션(Collection)의 요소를 필터링하거나 매핑하여 원하는 결과를 쉽게 얻을 수 있다.


람다식과 자바스크립트 익명 화살표 함수

만일 자바를 배우기 앞서 자바스크립트 프로그래밍을 먼저 배웠다면 자바의 람다 표현식을 이해하는데 있어 매우 수월할 것이다. 사실 자바스크립트의 익명 화살표 함수 자체가 람다 함수 일종이기 때문이다. 괄호를 생략하는 등 람다의 기본 문법 체계도 자바와 자바스크립트 둘 다 비슷하다. 단지 화살표 모양이 =>-> 로 다를 뿐이다.

 

람다식을 자바스크립트와 자바의 문법 형태를 비교하자면 아래 코드와 같다.

const MyFunction = {
    print: function() {}
};
MyFunction.print = (str) => console.log(str);
let myfunc = MyFunction;
myfunc.print("Hello World");

interface MyFunction {
    void print(String str);
}

public class Main {
    public static void main(String[] args) {
        MyFunction myfunc = (str) -> System.out.println(str);
        myfunc.print("Hello World");
    }
}

변수에 함수를 담을때, 자바스크립트는 약타입 언어라 타입에 관계없이 자유롭게 받을 수 있지만, 자바 같은 경우 강타입 언어이기 때문에 반드시 함수에 대한 타입을 선언하여야 한다.

하지만 자바에서는 8가지 타입(primitive 타입과 reference 타입) 밖에 없기 때문에 함수 데이터 자체를 담을수 있을만한 자료형이 딱히 적합한 것이 없다. 그래서 자바 개발진들은 인터페이스를 익명 구현 객체 타입으로써, 함수를 해당 인터페이스 타입으로 받을 수 있게 설계한 것이다.


람다식과 함수형 인터페이스

람다식의 형태를 보면 마치 자바의 메소드를 변수로 선언하는 것처럼 보이지만, 사실 자바는 메소드를 단독으로 선언할 수는 없다. 형태만 그렇게 보일 뿐이지 코드를 보면 람다 함수식을 변수에 대입하고, 변수에서 메소드를 호출해서 사용하는 것이 마치 객체와 다름이 없다.

 

사실 람다식도 결국은 객체이다. 정확히 말하면 인터페이스를 익명 클래스로 구현한 익명 구현 객체를 짧게 표현한 것 뿐이다.

객체 지향 방식 vs 람다 표현 방식

람다식의 형태를 보