람다
람다 정의
자바 8부터 도입된 람다는 자바에서 함수형 프로그래밍을 지원하기 위한 핵심 기능이다.
람다는 익명 함수이다. 따라서 이름 없이 함수를 표현한다.
보통 메서드나 함수는 다음과 같이 표현한다.
반환타입 메서드명(매개변수) {
본문
}람다는 다음과 같이 간결하게 표현한다.
(매개변수) -> {본문}
//이름이 없는 함수자바는 독립적인 함수를 지원하지 않으며, 메서드는 반드시 클래스나 인터페이스에 속한다.
👆 용어 - 람다와 람다식
람다 (Lambda) : 익명 함수를 지칭하는 일반적인 용어 (개념)
람다식 (Lambda Expression) :
(매개변수) -> {본문}형태로 람다를 구현하는 구체적인 문법 표현을 지칭한다.람다는 개념을 의미하고(넓은 의미), 람다식은 자바에서 그 개념을 구현하는 구체적인 문법을 의미한다.
람다는 변수처럼 다룰 수 있다.
Procedure procedure = () -> { // 람다를 변수에 담음
System.out.println("hello! lambda");
};
procedure.run(); // 변수를 통해 람다를 실행람다도 익명 클래스처럼 클래스가 만들어지고, 인스턴스가 생성된다.
익명 클래스의 경우 $로 구분하며 뒤에 숫자가 붙고, 람다의 경우 $$로 구분하며 뒤에 복잡한 문자가 붙는다.
함수형 인터페이스
함수형 인터페이스는 정확히 하나의 추상 메서드를 가지는 인터페이스를 말한다.
람다는 클래스, 추상 클래스에는 할당할 수 없다. 오직 단일 추상 메서드를 가지는 함수형 인터페이스에만 할당할 수 있다.
람다는 하나의 함수이다. 따라서 람다를 인터페이스에 담으려면 하나의 메서드(함수) 선언만 존재해야 한다.
인터페이스는 여러 메서드(함수)를 선언할 수 있는데, 이 중 하나에 할당해야 하는 문제가 발생한다.
자바는 이러한 문제를 해결하기 위해 단 하나의 추상 메서드만을 포함하는 함수형 인터페이스에만 람다를 할당할 수 있도록 제한했다.
👆 @FunctionalInterface
이 애노테이션을 통해 함수형 인터페이스임을 선언해두면 나중에 실수로 추상 메서드를 추가할 때 컴파일 오류가 발생한다.
따라서 함수형 인터페이스임을 보장할 수 있다.
람다를 사용할 함수형 인터페이스라면
@FunctionalInterface애노테이션을 필수로 추가하는 것을 권장한다.
람다와 시그니처
람다를 함수형 인터페이스에 할당할 때는 메서드의 형태를 정의하는 요소인 메서드 시그니처가 일치해야 한다.
메서드의 시그니처
이름 :
apply매개변수 :
int,int반환 타입 :
int
람다는 익명 함수이므로 시그니처에서 이름은 제외한다. 그 외 매개변수, 반환 타입이 함수형 인터페이스에 선언한 메서드와 맞아야 한다. (매개변수 이름은 상관없다. 타입과 순서만 맞으면 된다.)
또 다른 예시
이름 :
run매개변수 : 없음
반환 타입 : 없음
람다 생략
람다는 간결하게 코드를 작성할 수 있는 다양한 문법 생략을 지원한다.
매개변수와 반환 값이 없는 경우
타입 추론
이 함수형 인터페이스를 보면 이미
(int a, int b)로 매개변수의 타입이 정의되어 있다.이 정보를 사용하면 람다에서 타입 정보를 생략할 수 있다.
자바 컴파일러는 람다가 사용되는 함수형 인터페이스의 메서드 타입을 기반으로 람다의 매개변수와 반환값의 타입을 추론한다. 따라서 람다는 타입을 생략할 수 있다.
반환 타입은 문법적으로 명시할 수 없다. 대신에 컴파일러가 자동으로 추론한다.
매개변수 괄호 생략
매개변수가 정확히 하나이면서 타입을 생략하고 이름만 있는 경우 소괄호(
())를 생략할 수 있다.매개변수가 없는 경우 또는 매개변수가 둘 이상이면
()가 필수이다.
람다의 전달
람다는 함수형 인터페이스를 통해 변수에 대입하거나 메서드에 전달하거나 반환할 수 있다.
기본형이나 참조형이 변수에 값을 대입할 수 있는 것처럼 함수형 인터페이스로 선언한 변수에 람다 인스턴스의 참조값을 대입할 수 있다.
람다도 인터페이스(함수형 인터페이스)를 사용하므로 람다 인스턴스의 참조값을 변수에 전달할 수 있다.
변수에 참조값을 전달할 수 있으므로 다음과 같은 사용이 가능하다.
매개변수를 통해 메서드(함수)에 람다를 전달할 수 있다. (정확히는 람다 인스턴스의 참조값을 전달)
메서드가 람다를 반환할 수 있다. (정확히는 람다 인스턴스의 참조값을 반환)
람다를 메서드에 전달
메서드가 람다를 반환
람다는 함수형 인터페이스를 구현한 익명 클래스 인스턴스와 같은 개념이다.
람다를 변수에 대입한다는 것은 람다 인스턴스의 참조값을 대입하는 것이고, 람다를 메서드(함수)의 매개변수나 반환값으로 넘긴다는 것 역시 람다 인스턴스의 참조값을 전달, 반환하는 것이다.
람다를 자유롭게 전달하거나 반환할 수 있기 때문에 코드의 간결성과 유연성이 높아진다. 만약 익명 클래스를 작성했다면 매우 번잡했을 것이다.
👆 고차 함수 (Higher-Order Function)
고차 함수는 함수를 값처럼 다루는 함수를 의미하며, 일반적으로 다음 두 가지 중 하나를 만족하면 고차 함수라 한다.
함수를 인자로 받는 함수(메서드)
함수를 반환하는 함수(메서드)
자바에서 람다(익명 함수)는 함수형 인터페이스를 통해서만 전달할 수 있다. 즉 자바에서 함수를 주고받는다는 것은 함수형 인터페이스를 구현한 어떤 객체(람다 or 익명 클래스)를 주고받는 것과 같다.
고차 함수는 함수를 다루는 추상화 수준이 더 높다는 데에서 유래했다. 보통 일반적인 함수는 데이터(값)을 다루는데, 이것을 넘어 함수라는 개념 자체를 값처럼 다룬다는 점에서 추상화의 수준이 한 단계 높아진다고 해서 고차 함수라고 부른다.
Last updated