람다는 함수형 프로그래밍 기법을 지원하는 자바의 문법 요소를 말한다.
메서드를 하나의 식으로 표현한 것으로 코드가 매우 간결하면서 명확하게 표현할 수 있는 장점이 존재하며 자바도 JDK1.8 이후 함수형 프로그래밍 문법 요소를 도입하면서 객체지향 프로그래밍 + 함수형 프로그래밍 과 같이 혼합하는 방식으로 보다 효율적인 프로그래밍을 할 수 있게 되었다.
여기서 함수의 정의는 다음과 같다.
함수란?
프로그래밍에서 함수(function)란 하나의 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 프로그램 코드의 집합으로 정의할 수 있습니다. -TCP School, http://www.tcpschool.com/c/c_function_basic
위의 정의는 C언어에서 함수의 정의인데 자바에서는 함수는 메서드와 유사하고 메서드라고 봐도 좋을 것으로 생각된다.
보통 함수와 메서드가 공존하는 언어(예:파이썬)에서는 두 개를 구분하여 말하기도 하지만 자바는 메서드와 함수를 구분하여 말하지 않는다. 자바에서 사용되는 함수의 정확한 명칭은 메서드이다. - 점프 투 자바, https://wikidocs.net/225
람다식은 다음과 같은 형태로 작성 가능하다.
void hey() {
System.out.println("What?");
} // 기존의 메서드 표현 방식
() -> System.out.println("What?"); // 위의 코드를 람다식으로 표현한 식
람다식의 특징으로는 기본적으로 반환 타입과 이름을 생략할 수 있으며, 메서드 바디에 문장의 실행문이 하나만 존재할 때 중괄호와 return문을 생략할 수 있다. 다만 이 경우에는 세미콜론까지 생략해야한다. 또한 매개변수 타입을 함수형 인터페이스를 통해 유추할 수 있는 경우에는 매개변수의 타입을 생략할 수 있다.
public class Main {
public static void main(String[] args) {
sumFunctionalInterface s = (num1,num2) -> num1 + num2;
//위와 같이 람다식을 통해 익명객체를 선언하면서 생성할 수 있다.
}
@FunctionalInterface //함수형 인터페이스임을 알리는 애너테이션
interface sumFunctionalInterface{
int sum(int num1,int num2);//인터페이스 내부의 반환타입과 매개변수를 통해 람다식 작성시
//람다식의 반환타입과 매개변수 타입을 생략할 수 있다.
}
}
자바에서 함수를 사용하려면 클래스에 정의되고 해당 객체를 생성한 후 객체를 메서드로 호출해야한다. 이런 맥락에서 우리가 메서드와 동일시 여겼던 람다식 또한 객체임 정확히는 이름이 없기 때문에 익명 객체이다.
위의 예시와 같이 코드를 Intellij에서 작성할 경우 num1 + num+2 부분에 Lambda can be replaced with method reference 라는 메세지가 나타나게 되는데 수정하게 될 경우
sumFunctionalInterface s = Integer::sum;
위와 같이 코드가 변경되게 된다. 이것은 람다식에서 불필요한 매개변수를 제거할 때 주로 사용하는 메서드 참조인데 간단해진 익명 객체를 더욱 간단하게 사용할 수 있다.
메서드 참조는 정적메서드와 인스턴스 메서드가 차이가 있는데. 정적 메서드의 경우에는
클래스 :: 메서드
인스턴스 메서드의 경우에는
참조변수 :: 메서드
와 같은 방식으로 사용한다.
생성자도 참조가 가능한데 단순히 메서드 호출로 구성된 람다식을 메서드 참조로 대치할 수 있듯이 단순히 객체를 생성하고 리턴하도록 구성된 람다식은 생성자 참조로 대치 가능하다.
클래스 :: new
위와 같은 방식으로 사용되며 생성자가 오버로딩 되어 여러개가 있을 경우 컴파일러는 함수형 인터페이스의 추상 메서드와 동일한 매개변수 타입과 개수를 가지고 있는 생성자를 찾아 실행한다.