Stream API 람다 표현식
람다 표현식
- 자바에서는 인터페이스를 선언하거나 매개변수로 주어야 할 때 1회용 구현체인 익명 클래스를 사용할 수 있습니다.
- 예시를 보여드리겠습니다.
더보기
import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; public class LambdaClass { public static void main(String[] args) { List<Integer> list = Arrays.asList(2, 1, 3, 5, 4); // 오름차순 정렬 List<Integer> list2 = list.stream() .sorted(Comparator.naturalOrder()) .collect(Collectors.toList()); // 내림차순 정렬 List<Integer> list3 = list.stream() .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); System.out.println("-----------------------printList-----------------------"); printList(list); printList(list2); printList(list3); System.out.println("-----------------------printLambda-----------------------"); printLambda(list); printLambda(list2); printLambda(list3); } private static void printList(List<Integer> list) { // 1회용 구현체 new Consumer를 매개변수로 활용 list.forEach(new Consumer<Integer>() { @Override public void accept(Integer num) { System.out.print(num + " "); } }); System.out.println("\n"); } private static void printLambda(List<Integer> list) { list.forEach(num -> System.out.print(num + " ")); System.out.println("\n"); } } /* 출력 -----------------------printList----------------------- 2 1 3 5 4 1 2 3 4 5 5 4 3 2 1 -----------------------printLambda----------------------- 2 1 3 5 4 1 2 3 4 5 5 4 3 2 1 */
- 람다를 활용하여 printList의 내용을 더 간결하게 변경했습니다.
- 익명 클래스 new Consumer<Integer>(){}가 한 줄로 줄어들었으며 개발자의 의도가 드러나는 문장을 사용했습니다.
- forEach의 매개변수에 사용되는 Consumer 타입과 Consumer::accept가 겉으로 드러나지 않습니다.
람다 표현식이란
- 람다식은 익명 클래스를 간략하게 표현하는 방법입니다.
- 식 전체가 인스턴스로 취급됩니다.
람다 표현식 구조
- 람다 표현식은 기본적으로
이와 같은 구조를 가집니다.(parameter) -> expression (parameter) -> {statement;}
- 람다 표현식엔 인터페이스와 오버라이드할 메서드 이름이 표기되지 않습니다.
- 매개변수 목록을 왼쪽에 표기합니다.
- 매개변수는 타입을 생략할 수 있습니다.
- 매개변수가 1개면 괄호를 생략할 수 있습니다.
- 매개변수가 0개면 () ->으로 매개변수가 없음을 나타내어야 합니다.
- 매개변수 목록 작성이 끝나면 화살표 ->를 작성합니다.
- 화살표 우측에는 람다 바디를 작성합니다.
- 한 줄 (세미콜론 한 번)으로 구현할 수 있는 경우 expression입니다.
- expression은 중괄효, return, 세미콜론을 생략하여야 합니다.
- 예제
더보기
package lambdaExample; import java.util.function.BiFunction; import java.util.function.Function; import javax.xml.transform.Source; public class LambdaExample { public static void main(String[] args) { Example example = new Example(); example.example1(); example.example2(); example.example3(); } } class Example { public void example1() { Function<String, Integer> test = String::length; int result = test.apply("가나다라마"); System.out.println("\n-----------------------Expression 구현-----------------------"); System.out.println(result); } public void example2() { Runnable runnable = () -> System.out.println("Hello Lambda"); System.out.println("\n-----------------------매개변수가 없는 경우-----------------------"); runnable.run(); } public void example3() { BiFunction<Integer, Integer, Integer> print = (x, y) -> { return x * y; }; int result = print.apply(10, 10); System.out.println("\n-----------------------statement 구현-----------------------"); System.out.println(result); } } /* 출력 -----------------------Expression 구현----------------------- 5 -----------------------매개변수가 없는 경우----------------------- Hello Lambda -----------------------statement 구현----------------------- 100 */
람다 표현식 사용 범위
1. 함수형 인터페이스
- 함수형 인터페이스는 추상 메서드가 단 1개만 있는 인터페이스를 의미합니다.
- 특정 부모에게 상속받아 오버라이드한 클래스가 있는 경우는 함수형 인터페이스가 아닙니다.
- @FunctionalInterface로 이 인터페이스가 함수형 인터페이스임을 표시할 수 있습니다.
- @FunctionalInterface
- 함수형 인터페이스를 표현하는 어노테이션입니다.
- 이 어노테이션을 사용했으나 추상 메서드가 2개 이상이면 함수형 인터페이가 아니라는 경고를 표시합니다.
- @FunctionalInterface
자주 사용하는 함수형 인터페이스
1. 조건 검증
인터페이스 | 설명 |
Predicate<T> | T 타입을 매개변수로 받고 boolean을 반환합니다. 조건 검증에 사용합니다. |
BiPredicate<L, R> | L, R을 받고 boolean을 반환합니다. 주어진 두 매개변수를 사용하여 검증할 때 사용합니다. |
2. 자원 생성 / 소모
인터페이스 | 설명 |
Consumer<T> | T타입을 매개변수로 받고 반환 타입이 없습니다. |
Supplies<T> | 매개변수는 없으며 T 타입을 반환합니다. |
BiCunsumer<T, U> | T, U를 받고 반환은 하지 않습니다. 매개변수가 2개 필요하지만 반환 없이 자원을 소모하는 연산에 사용합니다. |
3. 연산
인터페이스 | 설명 |
Function<T, R> | T타입을 매개변수로 받고 R타입을 반환합니다. |
unaryOperator<T> | Function<T, R>을 상속받은 인터페이스이며 T, R을 같은 타입으로 사용합니다. T를 받고 T를 반환합니다. 단항 연산 시 사용합니다. |
BiFunction<T, U, R> | T, U를 매개변수로 받고 R을 반환합니다. T, U, R 모두 다른 타입을 유연하게 사용할 수 있습니다. |
BinaryOperator<T> | BiFunction<T, U, R>을 상속받은 인터페이스이며 T, U, R을 같은 타입으로 사용합니다. T, T를 받고 T를 반환합니다. |
매개변수와 반환형이 중복되는 함수형 인터페이스
- 람다식은 인터페이스 이름과 오버라이드할 메서드 이름을 명시적으로 나타내지 않습니다.
- 매개변수와 반환 타입이 완전 같은 함수형 인터페이스가 2개 이상 존재하는 경우 누구를 가리키는지 명확하지 않습니다.
'JAVA' 카테고리의 다른 글
[JAVA] - Stream API 이해 4 (0) | 2024.05.29 |
---|---|
[JAVA] - Stream API 이해 3 (0) | 2024.05.28 |
[JAVA] - Stream API 이해 1 (0) | 2024.05.25 |
[JAVA] - LocalDate, LocalDateTime 날짜 더하기 빼기 (0) | 2024.05.24 |
[JAVA] - 객체 지향 설계 5원칙 - S.O.L.I.D & 특징 4가지 (추상화, 상속, 다형성, 캡슐화) (1) | 2024.03.13 |