728x90
람다란 무엇인가?
람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이다.
즉, 람다는 어떤 함수의 매개변수로 다른 함수를 넣고 싶을 때 사용한다.
-
익명 : 보통의 메서드와 달리 이름이 없으므로 익명이라 표현한다.
-
함수 : 람다는 메서드처럼 특정 클래스에 종속되지 않으므로 함수라고 부른다.
-
전달 : 람다 표현식을 메서드 인수로 전달하거나 변수로 저장할 수 있다.
-
간결성 : 익명 클래스처럼 많은 자질구레한 코드를 구현할 필요가 없다.
람다의 구성 요소
- 파라미터 리스트
- 화살표 : 파라미터 리스트와 바디를 구분한다
- 바디 : 람다의 반환값에 해당하는 표현식
함수형 인터페이스는 정확히 하나의 추상 메서드를 지정하는 인터페이스이다.
@FunctionalInterface 어노테이션을 붙여 주면 메서드가 2개 이상일 경우 컴파일 단계에서 에러를 발생 시킬 수 있다.
함수형 인터페이스 사용
Predicate
java.util.function.Predicate 인터페이스는 test라는 추상 메서드를 정의하며 test는 제네릭 형식 T의 객체를 인수로 받아 boolean을 반환한다.
Consumer
java.util.function.Consumer 인터페이스는 제네릭 형식 T 객체를 받아서 void를 반환하는 accept라는 추상 메서드를 정의한다. T 형식의 객체를 인수로 받아서 어떤 동작을 수행하고 싶을 때 Consumer 인터페이스를 사용할 수 있다.
Function
java.util.function.Function 인터페이스는 제네릭 형식 T를 인수로 받아서 제네릭 형식 R 객체를 반환하는 apply라는 추상 메서드를 정의한다. 입력을 출력으로 매핑하는 람다를 정의할 때 Function 인터페이스를 활용할 수 있다. 자바 8에서는 기본형을 입출력으로 사용하는 상황에서 오토박싱 동작을 피할 수 있도록 특별한 버전의 함수형 인터페이스를 제공한다.
Supplier
매개 변수는 없고, 반환 값이 있는 함수형 인터페이스이다.
추상 메소드 T supplier()를 가진다.
메서드 레퍼런스
메서드 레퍼런스는 특정 메서드만을 호출하는 람다의 축약형이다. 메서드 레퍼런스를 새로운 기능이 아니라 하나의 메서드를 참조하는 람다를 편리게 표현할 수 있는 문법으로 간주 할 수 있다.
람다
|
메서드 레퍼런스 단축 표
|
(Apple a) → a.getWeight()
|
Apple::getWeight
|
() → Thread.currentThread().dumpStack()
|
Thread.currentThread()::dumpStack
|
(str, i) ⇒ str.substring(i)
|
String::substring
|
(String s) → System.out.println(s)
|
System.out::println
|
람다, 메서드 레퍼런스 활용하기
아래와 같은 순서로 사용하면 편하다
코드전달 → 익명 클래스 사용 → 람다 표현식 사용 → 메서드 레퍼런스 사용
Comparator는 Comparable 키를 추출해서 Comparator 객체로 만드는 Function 함수를 인수로 받는 정적 메서드 comparing을 포함한다. 그러므로 다음처럼 사용할 수 있다.
import static java.util.Comparator.comparing;
inventory.sort(comparing((a) -> a.getWeight()));
메서드 레퍼런스를 사용했을 때
inventory.sort(comparing(Apple::getWeight));
람다 표현식을 조합할 수 있는 유용한 메서드
역정렬
비교자 구현을 그대로 재사용하여 사과의 무게를 기준으로 역정렬할 수 있다.
// 무게를 내림차순으로 정렬
Inventory.sort(comparing(Apple::getWeight).reserved());
Comparator 연결
thenComparing은 함수를 인수로 받아 첫 번째 비교자를 이요해서 두 객체가 같다고 판단되면 두 번째 비교자에 객체를 전달한다.
// 무게를 내림차순으로 정렬하고 두 사과의 무게가 같으면 국가별로 정렬할것
inventory.sort(comparing(Apple::getWeight)
.recered()
.thenComparing(Apple::getContry));
Predicate 조합
Predicate 인터페이스는 복잡한 Predicate를 만들 수 있도록 negate, and, or 세 가지 메서드를 제공한다.
// 빨간색이면서 무거운(150그램 이상) 사과 또는 그냥 녹색 사과
Predicate<Apple> redAndHeavyAppleOrGreen =
redApple.and(a -> a.getWeight() > 150)
.or(a -> "green".equals(a.getColor()));
Function 조합
Function 인터페이스는 andThen, compose 두 가지 디폴트 메서드를 제공한다. andThen 메서드는 주어진 함수를 먼저 적용한 결과를 다른 함수의 입력으로 전달하는 함수를 반환한다.
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
int result = h.apply(1); // 4
compose 메서드는 인수로 주어진 함수를 먼저 실행한 다음에 그 결과를 외부 함수의 인수로 제공한다.
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g);
int result = h.compose(1); // 3
728x90
'Java & Spring' 카테고리의 다른 글
Spring Security 개념정리 (0) | 2024.03.12 |
---|---|
자바 모니터링 설정 (0) | 2024.01.30 |
H2 테스트DB에 mysql 함수 인식불가 에러 (0) | 2023.11.07 |
java maven을 gradle로 변환 (0) | 2023.09.24 |
java LinkedList 정리 (0) | 2021.08.21 |