람다란 ?
- 익명 함수를 의미한다
- 함수형 프로그래밍을 지원하기 위해 Java 8에서 도입되었다
- 사용하면 코드가 간결해진다는 장점이 있다
- 컬렉션과 Stream API를 사용할 때 매우 유용하다
- 주로 [[함수형 인터페이스]]와 함께 사용한다
왜 람다를 사용하나?
- 코드 간결성 및 가독성 향상
- 특히 컬렉션 요소를 처리하는 데 유용하다
- 익명 클래스나 반복적인 코드없이 간단하게 기능을 정의할 수 있다
- 함수형 프로그래밍 지원
- [[병렬 처리]] 및 스트림 API 강화
- 람다 표현식은 스트림 API를 간결하게 작성할 수 있게 도와준다
- 이벤트 처리 및 콜백 메커니즘 간소화
- 비동기식 프로그래밍에서 콜백을 간단하게 정의할 수 있다
함수형 인터페이스
- Consumer
- java.util.function 패키지
- void accpet(T t)를 가지고 있다
- 주어진 입력 인수 t에 대한 작업을 수행한다
- Function<T, R>
- 입력을 하나 받아서 하나의 출력을 반환하는 인터페이스이다
- R apply(T t)
Fucntion<Integer, String> intToString = i -> "Number = " + i; System.out.println(intToString.apply(3)); // 결과 Number = 5
- Predicate
- 입력을 하나 받아서 boolean을 반환하는 함수형 인터페이스이다
- Supplier
- 입력은 받지 않고, 값을 반환하는 인터페이스이다
- BiConsumer
- 두 개의 입력을 받아서 작업을 수행하고, 값을 반환하지 않는다
- void accept(T t, U u)
- BiFunction<T, U, R>
- 두 개의 입력을 받아서 하나의 출력을 반환한다
- R apply(T t, U u)
- UnaryOperator
- 하나의 입력을 받아서 동일한 타입의 결과를 반환한다
- Function<T, T>의 특수화이다
- T apply(T t)
- BinaryOperator
- 두 개의 동일한 타입을 입력 받아서 동일한 타입의 결과를 반환한다
- BiFunction<T, T, T>의 특수화이다
- T apply(T t1, T t2)
자바는 람다식을 어떻게 구현하고있나 ?
- 내부적으로 invokeDynamic 바이트코드 명령어와 함께 사용된다
- invokeDynamic은 런타임에 필요한 람다식을 동적으로 생성하고 호출한다
- 컴파일 시, JVM은 람다식을 바이트코드로 변환한다
- 이때, invokeDynamic 명령어가 사용되며, 런타임에 호출되는 메서드를 동적으로 연결한다
- java.lang.invoke 패키지의 MethodHandle과 LambdaMetaFactory를 사용해서 런타임에 람다식을 생성한다
- 이 과정에서 람다식은 실제로는 익명 클래스가 아닌, 바이트코드로 생성된다
- JVM이 컴파일하면서 람다식을 만나면 invokeDynamic을 명령어를 사용한다
- invokeDynamic이 붙은 코드는 런타임 환경에서 LambdaMetaFactory를 호출한다
- LambdaMetaFactory는 CallSite를 생성하고 이를 통해 람다식을 호출한다
- 람다식이 실제로 호출될 때 CallSite를 통해서 MethodHandle 사용된다
- MethodHandle은 함수형 인터페이스가 가지고 있는 메서드를 참조하고 있다
Stream API란 ?
- java 8에 추가된 기능으로 컬렉션이나 배열을 함수형 스타일로 처리할 수 있게 해준다
- 기존 반복문을 사용하는 방식보다 코드가 간결하고 가독성이 높아지는 장점이 있다
- 병렬 처리를 쉽게 구현할 수 있다
Stream API 특징
- 중간 연산과 최정 연산
- 중간 연산
- 스트림을 반환하지만 실제 처리는 이루어지지 않는 연산
- filter, map, sorted 등
- 최종 연산
- 스트림을 처리하여 결과를 생성하는 연산
- collect, forEach, reduce
- 중간 연산
- 지연 연산
- 중간 연산은 지연 연산된다 그리고 최종 연산이 호출될 때 실제로 처리된다
- 이를 통해서 성능 최적화를 할 수 있다
'TIL > Java & Spring Boot' 카테고리의 다른 글
@Transactional을 왜 사용하고 어떤 기능이 있나? (0) | 2024.06.02 |
---|---|
병렬 스트림 (1) | 2024.06.02 |
Timestamp와 LocalDateTime 타입 차이 (0) | 2023.09.14 |
묵시적 / 명시적 형 변환 (0) | 2022.08.03 |
객체 지향 언어의 특징인 상속을 알아보자! (0) | 2022.04.13 |