Java&Web

[Java] 람다식과 함수형 인터페이스(2)

프로그래민 2021. 3. 3. 00:40
반응형

[Java] 람다식과 함수형 인터페이스(1)

 

[Java] 람다식과 함수형 인터페이스(1)

람다식(Lambda Experssion)이란? 람다(Lambda)는 JDK 1.8부터 추가된 것으로, 람다의 도입으로 인해 자바는 객체지향언어이지만 함수형언어의 특징까지 가지게 되었다. 즉, 함수형 프로그래밍으로써 람다

minkwon4.tistory.com

 

람다가 도입된 이유

빅데이터를 프로그램적으로 다룰 수 있는 방법이 필요해지면서 멀티 코어를 활용한 분산 처리, 즉 병렬화 기술이 필요했다. 이에 따라 자바에서는 병렬화를 위해 컬렉션(배열, List, Set, Map)을 강화했고, 이러한 컬렉션을 더 효율적으로 사용하기 위해 스트림을 강화했다. 또 스트림을 효율적으로 사용하기 위해 함수형 프로그래밍, 람다의 도입이 있었다.

빅데이터 지원 -> 병렬화 강화 -> 컬렉션 강화 -> 스트림 강화 -> 람다 도입 -> 인터페이스 명세 변경 -> 함수형 인터페이스 도입

람다란 한 마디로 코드 블록이다. 기존의 코드 블록은 메소드 내에 존재해야 했다. 그래서 코드 블록만 갖고 싶어도 기존에는 코드 블록을 위해 메소드를, 다시 메소드를 사용하기 위해 익명 객체를 만들거나 하는 식이었다. 람다의 도입 이후론 코드 브록인 람다를 메소드의 인자나 반환값으로 사용할 수 있게 되었다. 즉, 익명 객체조차 없이 바로 코드 블록만 사용할 수 있게 되었다. 

 

함수형 인터페이스

추상 메소드를 하나만 갖는 인터페이스를 함수형 인터페이스라고 한다. 이러한 함수형 인터페이스만를 람다식으로 변경할 수 있다. @FunctionalInterface는 붙을 경우 컴파일러는 인터페이스가 함수형 인터페이스의 조건에 맞는지, 즉 단 하나의 추상 메소드만을 갖고 있는지 확인한다. 

자바 8의 java.util.function 패키지에는 다양한 함수형 인터페이스가 제공된다.

함수형 인터페이스 추상 메소드 용도
Runnable void run() 실행할 수 있는 인터페이스
Supplier<T> T get() 제공할 수 있는 인터페이스
Consumer<T> void accept(T t) 소비할 수 있는 인터페이스
Function<T, R> R apply(T t) 입력을 받아서 출력할 수 있는 인터페이스
Predicate<T> Boolean test(T t) 입력을 받아 참/거짓을 단정할 수 있는 인터페이스
UnaryOperator<T> T apply(T t) 단항(Unary) 연산할 수 있는 인터페이스
BiConsumer<T, U> void accept(T t, U u) 이항 소비자 인터페이스
BiFunction<T, U, R> R apply(T t, U u) 이항 함수 인터페이스
BiPredicate<T, U> Boolean test(T t, U u) 이항 단정 인터페이스
BinaryOperator<T, T> T apply(T t, T t) 이항 연산 인터페이스

 

컬렉션 스트림에서 람다 사용

람다는 다양한 용도가 있지만 그 중에서도 컬렉션 스트림을 위한 기능에 크게 초점이 맞춰져 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Integer[] ages = {2025183050};
 
//스트림 + 람다 미적용
for(int age : ages) {
    if(age < 20) {
        System.out.println(age);
    }
}
 
//스트림 + 람다 적용
Arrays.stream(ages)
    .filter(age -> age < 20)
    .forEach(age -> System.out.println(age));
 
                                                                                                

 

메소드 레퍼런스

메소드 레퍼런스 유형 람다식의 인자 예제
클래스::정적메소드 정적 메소드의 인자가 된다. Math::sqrt

num -> Math.sqrt(num)
인스턴스::인스턴스메소드 인스턴스 메소드의 인자가 된다. System.out::println

sqrtNum -> System.out.println(sqrtNum)
클래스::인스턴스메소드 첫 번째 인자는 인스턴스가 되고 그 다음 인자(들)는 인스턴스 메소드의 인자(들)가 된다. Intger::comapreTo

(a, b) -> a.compareTo(b)

 

반응형