Java & Spring

java8 람다 표현식

닥치고개돌 2024. 3. 1. 22:58
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

 

람다, 메서드 레퍼런스 활용하기

아래와 같은 순서로 사용하면 편하다

코드전달 → 익명 클래스 사용 → 람다 표현식 사용 → 메서드 레퍼런스 사용

ComparatorComparable 키를 추출해서 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