티스토리 뷰
람다식은 기본적으로 함수형 인터페이스를 표현합니다.
보통 함수형 인터페이스는 1개의 추상 메서드만 포함하는 인터페이스를 뜻합니다.
람다식은 Java8에 추가되었으며 아래와 같은 기능을 제공합니다.
1. 기능을 인수로 다룰수있으며 코드를 데이터로 처리할 수 있습니다.
2. 클래스에 속하지 않는 메서드를 만들 수 있습니다.
3. 람다식은 객체인 것 처럼 전달될 수 있으며 요청 시 실행될 수 있습니다.
람다 따라해보기
Comparator를 익명 클래스와 람다식을 이용하여 구현한 것의 차이입니다.
익명 클래스 방식에 비해 굉장히 간결해졌습니다.
이제 람다식을 사용하여 1개의 기능을 만들어보겠습니다.
interface에 body가 없는 abstract method를 1개 정의합니다.
"함수형 인터페이스를 정의한다"라고 말할 수 있습니다.
위에서 작성한 함수형 인터페이스를 선언하고
new 키워드가 붙는 인스턴스 할당 위치에
함수형 인터페이스의 abstract method 구현체를 넣어줍니다.
인자가 2개 있는 함수형 인터페이스입니다.
람다식을 사용하여 구현하겠습니다.
람다의 룰
1. (x) -> System.out.print(x); :
문이 1개인 경우 중괄호를 생략할 수 있습니다.
2. x -> System.out.println(x); : 단일 인자인 경우 빈 괄호 사용이 가능합니다.
3. (x, y) -> {
int z = x+ y;
return z;
} :
문이 2개 이상이면 중괄호를 사용해야 합니다.
4. () -> body : 인자가 없는 경우 빈 괄호로 표현합니다.
5. () -> 1 :단일 문이면 return 키워드 생략 가능
람다식은 함수형 인터페이스의 구현에만 사용할 수 있습니다.
인자의 타입이 생략이 가능한 이유입니다.
2개 이상의 추상 메서드를 포함하는 인터페이스에 람다식을 사용하는 경우 컴파일러는
어떤 메서드 사용하는지도 모르며 구현이 안된 추상 메서드를 가지는
인스턴스를 제어하는 일이 발생할 수 있습니다.
final
함수형 프로그래밍 자체가 상태를 가질 수 없는 불변형이다.
함수형 프로그래밍을 하기 위한 기술에서 값이 바뀌면 함수형 프로그래밍이라 할 수 없다.
익명 클래스와 람다의 차이
비슷한 듯 다릅니다. 익명 클래스는 함수형 인터페이스만이 아니라
인터페이스, 추상 클래스 구현에 모두 사용이 가능하나
람다는 함수형 인터페이스의 구현에만 사용 가능합니다.
두 방식은 컴파일이 된 후 바이트코드에서도 다른 양상을 보입니다.
익명 클래스는 새로운 클래스를 생성하지만
람다는 새로운 메서드를 생성합니다.
Variable Capture
람다의 바디에서는 외부의 값을 참조할 수 있습니다.
파라미터의 값을 참조하지 않고 람다식 body 밖의 값을 참조합니다.
이렇게 외부에서 정의된 변수를 자유 변수(free variable)라고 말합니다.
지역변수는 stack영역에 적재가 되며 스레드의 생명주기가 종료되면 stack영역도 사라집니다.
그래서 람다가 참조하고 있는 스레드의 stack에 적재된 지역변수를 자신의 stack에 복사합니다.
이렇게 복사하여 참조하는 것을 람다 캡쳐링(lambda capturing)이라고 합니다.
getLambda method가 종료되고 값을 반환하여도
freeVariable값을 복제하여(reference by value) 사용중입니다.
(글쓴이는 capturing에서 나오는 stack을 stack frame이라고 생각합니다.)
하지만 조건이 붙습니다.
참조하는 외부 값은 final이거나 effectively final이어야 합니다.
참조 이전에 값이 할당되어야 합니다.
메서드, 생성자 레퍼런스
메소드 레퍼런스는 람다 표현식이 단 하나의 메소드만을 호출하는 경우
불필요한 매게변수를 제거하고 간결하게 코드를 작성할 수 있도록 도와줍니다.
기본적인 사용법은 매게변수를 제거하고 '::' 기호를 사용합니다.
클래스명::메서드명
참조 변수명::메서드명
점점 짧아지고 간결해집니다.
메서드 참조에는 3가지 방식이 있습니다.
1. static method
Sayable Interface를 정의하고 static method saySomething을 참조합니다.
Thread 생성자에 runnable인자 자리에 사용합니다.
2. instance method
생성된 instance의 method를 참조합니다.
3. constructor
new 키워드를 사용하여 생성자를 참조합니다.
Messageable의 getMessage를 Message class의 생성자로 구현해줍니다.
그 아래 라인에 getMessage를 호출하면 Message class의 생성자가 호출됩니다.
'Java & Kotlin' 카테고리의 다른 글
Java 얕은 복사, 깊은 복사 (0) | 2023.01.26 |
---|---|
Java Collection Framework (0) | 2022.12.14 |
Java raw type (0) | 2022.12.12 |
Java Generic (0) | 2022.12.12 |
Java NIO (0) | 2022.12.11 |
- Total
- Today
- Yesterday
- 백엔드
- jvm
- springboot
- jre
- java8
- jre8
- 자사서비스
- boot 일대다
- 자바
- jre11
- 코딩테스트
- 스택
- jdk11
- mappedby
- 프로그래머
- 개발자채용
- 문제
- 스타트업
- 백준 제로 자바
- JDK8
- 백준 제로
- Spring
- 백준
- JDK
- JPA
- 다대일
- ㅃ
- 관계설정
- 알고리즘
- boot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |