본문 바로가기
Java/study

람다식(Lambda Expression)

by avvin 2019. 4. 18.

람다식(Lambda Expression)


익명함수를 생성하기 위한 식, 객체 지향보다는 함수지향

객체지향언어인 자바에서 람다식 수용한 이유 : 컬렉션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있다.

형태는 매개변수를 가진 코드 블록이며, 인터페이스 변수에 대입된다. (=인터페이스의 익명구현객체를 생성한다.)


Runnable runnable = ()-> {}; // 람다식 자체로 객체 생성이 되기때문에 new 키워드 쓸 필요 X

람다식은 단순히 메소드를 선언하는 것이 아니라 이 메소드를 가지고 있는 객체를 생성해 낸다.

(익명구현객체처럼 바이트 코드파일로 생성되는지 확인해보기)


Runnable runnable = ()-> {}; // 람다식 자체로 객체 생성이 되기때문에 new 키워드 쓸 필요 X


람다식은 대입될 인터페이스의 종류(추상메서드의 선언 형태에 따라)에 따라 작성 방법이 달라짐

람다식이 대입될 인터페이스람다식의 타겟타입(target type)이라고 한다.

위 람다식의 타겟타입은 Runnable



( 타입 매개변수 ) -> { 실행문 } ;


런타임시에는 익명구현 객체를 생성한다.


-> : 매개변수를 이용해서 중괄호 안의 실행문을 실행한다.


( int a ) -> { System.out.println(a); }


( 타입 매개변수 ) -> { 실행문 } ; 


매개변수 타입은 런타임 시 대입되는 값에 따라 자동으로 인식될 수 있기 때문에 일반적으로 매개변수의 타입을 언급하지 않는다.


매개 변수가 하나면 소괄호 생략가능

실행문도 하나면 중괄호 생략가능


 a  ->  System.out.println(a); 


매개변수가 없을 경우엔 빈 괄호 사용 

람다식의 (매개변수)는 타겟타입인 함수적 인터페이스의 추상메서드의 매개변수이기때문에 

추상메서드가 매개변수를 가지지 않으면 람다식의 매개변수 자리에도 빈 괄호가 온다.



실행문으로 return문만 있을 경우, 


( x, y ) -> { return x+y ; } ;


( x, y ) -> x + y 





함수적 인터페이스 ( @FunctionalInterface : 인터페이스가 갖는 추상메서드 개수를 검사하는 어노테이션, 선택적으로 사용 )


람다식은 하나의 메서드만을 정의하기 때문에 두 개 이상의 추상 메서드가 선언된 인터페이스는 람다식의 타겟타입이 될 수 없다.


추상메서드 하나만 선언된 인터페이스 = 함수적 인터페이스




람다식에서 클래스 멤버와 로컬변수 사용


람다식의 실행블록에는 (람다식이 포함된, 선언된)클래스의 멤버(필드와 메서드) 및 

( 람다식이 메서드 내부에서 선언된 경우 )메서드의 매개변수나 로컬변수를 사용할 수 있다. 

(람다식은 메서드 내부에서 주로 작성, 로컬 익명구현객체를 생성시킨다고 봐야한다.)


클래스의 멤버를 사용할 때엔 this 키워드 사용 가능

일반적으로 익명객체 내부에서 쓰이는 this는 익명객체의 참조이지만 람다식에 쓰이는 this는 람다식을 실행한 객체(람다식이 선언된 클래스)의 참조 


메서드의 로컬변수나 매개변수를 사용할때 이 변수들은 final 특성(한번만 초기화할 수 있다)을 가져야한다. 

<<<1권 9.5.3 익명객체의 로컬변수 사용 다시 읽고 정리해서 포스팅하기 // --> '로컬 객체의 로컬변수 사용' 포스팅

람다식 내부에 쓰인 매개변수나 로컬변수는 final 특성을 가지게되어 람다식 내부 또는 외부에서 변경할 수 없다.



Thread의 하위 클래스가 아닌, new Thread(매개값)를 사용하여 스레드 객체를 직접 생성할 때 매개값으로 인터페이스의 구현 객체를 주는데

이 때, 람다식도 사용 가능. 스레드의 객체를 생성할 때, 람다식을 매개값으로 줄 수 있다.



메서드 참조


메서드를 참조해서 매개변수의 정보 및 리턴 타입을 알아내어 람다식에서 불필요한 매개변수 제거하는 것이 목적

정적 또는 인스턴스 메서드를 참조할 수 있고, 생성자 참조도 가능


정적메서드 참조

클래스 :: 메서드


인스턴스 메서드 참조

객체 생성 후

참조변수 :: 메서드


생성자 참조

단순히 객체를 생성하고 리턴하도록 구선된 람다식은 생성자 참조로 대치 가능

람다식 : ( a, b ) -> { return new 클래스(a, b); }


생성자 참조 :: 클래스 :: new





공부한 내용 정리)


람다식은 함수 지향


메서드는 반드시 클래스, 인터페이스 내에 선언되어야한다.

추상메서드를 하나만 가지고 있어서 함수적 역할만을 하는 인터페이스를 함수적 인터페이스라고 한다.

람다식은 함수적 인터페이스의 익명구현 객체이므로 함수적 역할만 하는 구현 객체라고 보면 된다.

메서드의 역할을 하므로 매개변수를 가질 수 있고, 객체이므로 인터페이스 타입을 매개값으로 받는 함수의 매개값으로 쓰일 수 있다.

람다식을 매개값으로 받는 메서드는 매개변수를 가질수 있는 메서드를 매개값으로 받는 셈


함수 형태로 매개변수에 받아와서 매개변수에서 dot을 통해 인터페이스의 메서드로 접근하면 된다.

일반 객체를 매개값으로 받아와서 객체를 통해 메서드로 접근하여 사용하는 것과 다를게 없다.


따로 소스파일을 생성할 필요 없이 객체를 생성해 사용할 수 있다는 점에서 익명구현 객체와 크게 다를게 없고, 

메서드 명을 작성할 필요도, 현재 클래스의 객체를 생성해서 접근할 필요도 없으므로(this는 람다식이 선언된 클래스의 인스턴스) 

익명구현 객체보다 쓰기도 간편하다.

다만, 람다식은 한 가지 함수만 쓸 수 있다(함수 지향)


디폴트 메서드와 정적 메소드는 추상메서드가 아니기때문에 함수적 인터페이스에 선언되어도 함수적 인터페이스의 성질을 잃지않는다.




람다식 튜토리얼 예제 3개

(임시저장)



'Java > study' 카테고리의 다른 글

컬렉션 프레임워크(Collection Framework)  (0) 2019.04.19
로컬 객체의 로컬 변수, 매개 변수 사용  (0) 2019.04.19
제네릭(Generic)  (0) 2019.04.17
멀티스레드 Synchronized Account Testing  (0) 2019.04.16
멀티스레드  (0) 2019.04.16