람다식 (Lambda Expressions)
- 익명 함수를 생성하기 위한 식
- 객체 지향 언어보다 함수 지향 언어
- 객체 지향 프로그래밍과 함수적 프로그램 혼합함으로써 더욱 효율적인 프로그래밍 가능
자바에서 람다식을 사용하는 이유
- 코드 간결
- 필터링 또는 매핑을 통해 대용량 데이터를 쉽게 집계
- (반복문에서 실행 속도 느리다는 단점)
람다식의 형식
- 매개변수를 가진 코드 블록
- 인터페이스 변수에 대입
- 하나의 메소드 정의
- 런타임 시에는 익명 구현 객체 생성
-
자바의 메소드 선언처럼 보임
-
람다식은 단순히 메소드를 선언하는 것이 아니라 해당 메소드를 가지고 있는 객체 생성
-
인터페이스 변수에 대입되어 인터페이스 익명 구현 객체 생성
-
익명 구현 객체 코드를 람다식을 사용하여 좀 더 간결하게 작성 가능
함수적 스타일의 람다식 작성법
- (타입 매개변수, ….) -> { 실행문; … }
(int a) -> { System.out.println(a); }
기호 ->
- 매개변수를 이용해서 중괄호 { } 실행한다는 의미
람다식의 다양한 표현 방법
(타입 매개변수, ….) -> { 실행문; … }
(int a) -> { System.out.println(a); }
(1) 매개변수 타입은 런타임 시에 대입되는 값에 따라 자동 인식될 수 있기 때문에 매개변수 타입 생략 가능
(a) -> { System.out.println(a); }
(2) 매개변수가 1개인 경우 괄호 생략 가능
a -> { System.out.println(a); }
(3) 실행문이 1개인 경우 중괄호 {} 생략 가능
a -> System.out.println(a);
(4) 매개변수가 없는 경우에는 반드시 빈 괄호 있어야 함
( ) -> { System.out.println(a); }
(5) 반환값이 있는 경우 return 문 사용
(x, y) -> { return x+y; }
(6) 중괄호 { } 안에 return 문만 있는 경우, return 생략 가능
(x, y) -> x+y;
타겟 타입
- 람다식이 대입될 인터페이스
- 람다식은 대입될 인터페이스의 종류에 따라 작성 방법 달라짐
함수적 인터페이스
@FunctionalInterface
- 람다식의 타겟 타입으로 모든 인터페이스를 사용하는 것은 아님
- 하나의 추상 메소드가 선언된 인터페이스만 람다식의 타겟 타입이 될 수 있음 (함수적 인터페이스)
- 람다식은 하나의 메소드 정의
@FunctionalInterface 어노테이션
- 함수적 인터페이스(추상 메소드 1개)임을 표시하는 어노테이션
- 함수적 인터페이스를 작성할 때 2개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 확인
- 2개 이상 선언되면 컴파일 오류 발생
@FunctionalInterface 어노테이션 생략
- @FunctionalInterface 어노테이션 선택 사항
- 이 어노테이션이 없어도 추상 메소드가 1개이면 모두 함수적 인터페이스
- 그러나 2개 이상의 추상 메소드가 선언되지 않도록 하기 위해서는 이 어노테이션 사용하는 것이 좋음
외부 로컬 변수 접근
람다식 실행 블록에서 클래스 멤버(필드와 메소드)와 사용
- 사용하는데 제약 사항 없음
- this 키워드 사용 시 주의
- 람다식에서 this : 람다식을 실행한 객체 참조
- 익명 객체 내부에서 this : 익명 객체 참조
람다식 실행 블록에서 로컬 변수 사용
- 제약 사항 있음 : final 특성을 가져야 함
- 메소드의 매개변수 또는 로컬 변수는 final 특성을 가져야 함
- 따라서 매개변수 또는 로컬 변수를 람다식에는 읽는 것은 허용되지만
- 람다식 내부 또는 외부에서 변경할 수 없음
- final 키워드 생략해도 final 특성 (Java 8 부터)