"이것이 자바다" 정리 14장 람다식

2023. 3. 21. 17:31자바/이론 공부

이 게시글은 내가 "이것이 자바다" 책을 읽고 노트에 정리해놨던 내용들을 검색하기 쉽게 데이터로 백업하는 용도의 글이다.

 

문제가 된다면 삭제하겠음.

 

 

 

14장 람다식

 

 

 

*최근 함수적 프로그래밍이 부곽됨.

 - 병렬 처리와 이벤트 지향 프로그래밍에 적합하기 때문.

 

 

*자바는 함수적 프로그래밍을 위해 람다식 지원.

 

 

*람다식

 - 익명함수를 생성하기 위한 식.

 - 람다식을 사용하면, 자바코드가 매우 간결해지고 컬렉션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있음.

 - 람다식은 매개변수를 가진 코드 블록 형태이지만, 런타임 시에는 익명구현 객체를 생성함.

(메소드처럼 생겼지만 해당 메소드를 포함하고 있는 익명 구현 객체다)

//원래 익명 구현 객체
Runnable runnable = new Runnable() {
	public void run() { ... }
}

//람다식 활용
Runnable runnable = () -> { ... };

 - 어떤 인터페이스를 구현할 것인가는 대입되는 인터페이스가 무엇이냐에 달려있다.(위에서 대입되는 인터페이스 : Runnable)

 

 

*람다식 기본 문법

/*
1. 기본

(타입 매개변수, ...) -> {실행문; ...}
- ()는 오른쪽 {} 중괄호를 실행하기 위해 필요한 값 제공.
- -> 기호는 매개 변수를 이용해서 중괄호 {}를 실행한다는 뜻.
 */
(int a) -> {System.out.println(a);}

/*
2.

- 매개 변수 타입은 런타임 시에 대입되는 값에 따라 자동으로 인식됨.
=> 람다식에서는 매개 변수의 타입을 일반적으로 언급하지 않음.
*/
(a) -> {System.out.println(a);}

/*
3.

- 하나의 매개변수만 있다면 ()괄호 생략.
- 하나의 실행문만 있다면 중괄호 {} 생략.
*/
a -> System.out.println(a)
/*
1. 기본

-return문이 있는 람다식
*/
(x, y) -> {return x+y;};

/*
2.

-중괄호 {}에 return문만 있을 경우, 람다식에서 return문을 사용하지 않고 다음과 같이 작성
*/
(x, y) -> x+y
//만약 매개변수가 없다면 다음과 같이 빈 괄호() 반드시 사용.
() -> { ... }

 

 

*타겟 타입

 - 람다식은 익명 구현 클래스를 생성하고 객체화함.

 - 람다식은 대입될 인터페이스의 종류에 따라 작성 방법이 달라지기 때문에 람다식이 대입될 인터페이스를 람다식의 타겟 타입(targetType) 이라고 함.

 

 

*함수적 인터페이스

 - 하나의 추상 메소드가 선언된 인터페이스만이 람다식의 타겟 타입이 될 수 있는데, 이러한 인터페이스를 함수적 인터페이스라고 한다.

 - @FunctionalInterface

    - 함수적 인터페이스를 작성할 때 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체킹해주는 기능

    - 이 어노테이션이 없더라도 하나의 추상 메소드만 있다면 모두 함수적 인터페이스이다.

 

 

*람다식의 실행 블록에는 클래스의 멤버(필드, 메소드) 및 로컬 변수를 사용할 수 있다. but 로컬 변수는 제약 사항이 따른다.

 

 

*람다식에서의 this 사용

 - 일반적으로 익명 객체 내부에서 this는 익명 객체의 참조지만, 람다식에서 this는 내부적으로 생성되는 익명 객체의 참조가 아니라 "람다식을 실행한 객체의 참조"이다.

 

 

*람다식에서의 로컬 변수 사용

 - 람다식은 로컬 익명 구현 객체를 생성시킨다.

 - 메소드의 매개 변수 또는 로컬 변수를 사용하면 이 두 변수는 final특성을 가져야 한다.

    - 람다식은 익명구현 객체를 생성한다. => Heap에 저장된다.

    - 지역변수는 Stack영역에 저장된다. => Stack영역은 스레드가 끝나면 사라진다.

    - final은 method영역에 저장된다. => final은 JVM이 끝날때까지 데이터가 유지된다.

    => 람다식에서 로컬 변수 사용시, (스레드가 끝나면 사라지는 Stack 영역의) 로컬 변수와 동기화가 되지않아 에러가 발생한다. => 로컬 변수가 final특성을 가져야지만 동기화가 되고 에러가 발생하지 않는다.