(자바) 함수형 프로그래밍과 람다 표현식
※ 본 포스팅은 이지스 퍼블리싱 출판 "Do it! 자바 프로그래밍 입문" 책의 내용을 참고해서 작성 했습니다.
■ 함수형 프로그램이란?
함수형 프로그래밍이란 함수의 구현과 호출만으로 프로그램을 만들 수 있는 프로그래밍 방식을 의미한다.
함수형 프로그래밍은 순수 함수(pure function)를 구현하고 호출함으로써 외부 자료에 영향을 주지 않도록 구현하는 방식이다.
여기서 순수 함수란 입력받는 자료 외 외부 자료를 사용하지 않아 함수의 기능이 자료에 독립적임을 의미한다. 즉, 동일 결과를 보장하고, 다양한 자료에 같은 기능을 수행할 수 있다.
이러한 함수형 프로그램은 코드의 가독성을 높이고 유지보수를 편리하게 하기 위해 등장했다.
■ 람다(Lambda) 표현식이란?
자바에서 제공하는 함수형 프로그래밍 방식을 람다 표현식(Lambda Expression)이라고 한다.
람다 표현식을 한마디로 말하자면 이름이 없는 익명 함수를 만드는 것이라고 보면 된다.
람다의 특징은 다음과 같다.
- 익명: 보통의 메서드와 달리 이름이 없는 익명으로 표현한다. 그렇기 때문에 코드가 간결하고 직관적이다.
- 함수: 람다는 메서드처럼 특정 클래스에 종속되지 않으므로 함수라고 부른다.
- 전달: 람다 표현식을 머세드 인수로 전달하거나 변수로 저장할 수 있다.
■ 람다 표현식 문법
//// 형식: (매개변수) -> {실행문;}
int add(int x, int y){
return x + y
}
//// ↓ 람다 표현식 ↓
(int x, int y) -> {return x+y;}
//// 매개변수는 자료형을 생략할 수 있다.
str -> {System.out.println(str);}
//// 매개변수가 두 개 이상인 경우에는 괄호를 생략할 수 없다.
(x, y) -> {System.out.println(x+y);}
//// 실행문이 한 문장인 경우 중괄호를 생략할 수 있다.
str -> System.out.println(str);
//// 실행문이 한 문장이더라도 명시적으로 return문을 이용하면 중괄호를 생략할 수 없다.
str -> {return str.length();}
//// 실행문이 한 문장인 경우 return문을 생략할 수 있다.
str -> str.length() // 두 값을 더하여 반환한다.
(x, y) -> x + y // 문자열의 길이를 반환한다.
■ 함수형 인터페이스
함수형 인터페이스란 람다 표현식을 쓰기 위한 인터페이스다. 자바는 참조 변수 없이 메서드를 호출할 수 없다. 따라서 람다 표현식을 구현하기 위해서는 함수형 인터페이스를 만들고, 인터페이스에 람다식으로 구현할 메서드를 선언한다.
람다 표현식은 하나의 메서드를 구현하여 인터페이스형 변수에 대입하므로 인터페이스가 두 개 이상의 메서드를 가져서는 안된다.
@FunctionalInterface 어노테이션
인터페이스를 선언할 때 @FunctionalInterface 어노테이션을 사용하면 함수형 인터페이스라는 의미이고, 메서드를 하나 이상 선언하게 되면 오류가 발생된다.
함수형 인터페이스는 정확히 하나의 추상 메서드를 지정하는 인터페이스다. 자바 API의 함수형 인터페이스로는 Comparator, Runnable 등이 있다.
/// java.util
public interface Comparator<T> {
int compare(T o1, T o2);
}
/// java.lang
public interface Runnable {
void run();
}
@FunctionalInterface
public interface MaxNumber {
int getMax(int num1, int num2);
}
public class Test {
public static void main(String args []){
// 람다를 이용한 Runnable 객체 생성
// 인터페이스를 구현하지 않고도 사용 가능하다
Runnable r = () -> System.out.println("Hello World!");
MaxNumber max = (x,y) -> (x>=y) ? x : y;
System.out.println(max.getMax(10, 20));
}
}