자바에서 제공되는 표준 API에서 한 개의 추상 메소드를 가지는 인터페이스들은 모두 람다식을 이용해서 익명 구현 객체로 표현이 가능하다. 예를 들어 스레드의 작업을 정의하는 Runnable 인터페이스는 매개 변수와 리턴값이 없는 run() 메소드만 존재하기 때문에 다음과 같이 람다식을 이용해서 Runnable 인스턴스를 생성시킬 수 있다.
// RunnableExample.java -- 함수적 인터페이스와 람다식
public class RunnableExample {
public static void main(String[] args) {
Runnable runnable = () -> {
for(int i=0; i<10; i++) {
System.out.println(i);
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
Thread 생성자를 호출할 때 다음과 같이 람다식을 매개값으로 대입해도 된다.
Thread thread = new Thread(() -> {
for(int i=0; i<10; i++) {
System.out.println(i);
}
});
자바 8부터는 빈번하게 사용되는 함수적 인터페이스(functional interface)는 java.util.function 표준 API 패키지로 제공한다. 이 패키지에서 제공하는 함수적 인터페이스의 목적은 메소드 또는 생성자의 매개 타입으로 사용되어 람다식을 대입할 수 있도록 하기 위해서이다. 자바 8부터 추가되거나 변경된 API에서 이 함수적 인터페이스들을 매개 타입으로 ㅁ낳이 사용한다. 물론 여러분이 개발하는 메소드에도 이 함수적 인터페이스들을 매개 타입으로 사용할 수 있다. java.util.function 패키지의 함수적 인터페이스는 크게 Consumer, Supplier, Function, Operator, Predicate로 구분된다. 구분 기준은 인터페이스에 선언된 추상 메소드의 매개값과 리턴값의 유무이다.
종류 | 추상 메소드 특징 | |
Consumer | - 매개값은 있고, 리턴값은 없음 | 매개값->Consumer |
Supplier | - 매개값은 없고, 리턴값은 있음 | Supplier->리턴값 |
Function | - 매개값도 있고, 리턴값도 있음 - 주로 매개값을 리턴값으로 매핑(타입 변환) |
매개값->Function->리턴값 |
Operator | - 매개값도 있고, 리턴값고 있음 - 주로 매개값을 연산하고 결과값을 리턴 |
매개값->Operator->리턴값 |
Predicate | - 매개값은 있고, 리턴 타입은 boolean - 매개값을 조사해서 true/false를 리턴 |
매개값->Predicate->boolean |
Consumer 함수적 인터페이스
Consumer 함수적 인터페이스의 특징은 리턴값이 없는 accept() 메소드를 가지고 있다. accept() 메소드는 단지 매개값을 소비하는 역할만 한다. 여기서 소비한다는 말은 사용만 할 뿐 리턴값이 없다는 뜻이다.
매개 변수의 타입과 수에 따라서 아래와 같은 Consumer들이 있다.
인터페이스명 | 추상 메소드 | 설명 |
Consumer<T> | void accept(T t) | 객체 T를 받아 소비 |
BiConsumer<T, U> | void accept(T t, U u) | 객체 T와 U를 받아 소비 |
DoubleConsumer | void accept(double value) | double 값을 받아 소비 |
IntConsumer | void accept(int value) | int 값을 받아 소비 |
LongConsumer | void accept(long value) | long 값을 받아 소비 |
ObjDoubleConsumer<T> | void accept(T t, double value) | 객체 T와 double 값을 받아 소비 |
ObjIntConsumer<T> | void accept(T t, int value) | 객체 T와 int 값을 받아 소비 |
ObjLongConsumer<T> | void accept(T t, long value) | 객체 T와 Long 값을 받아 소비 |
Consumer<T> 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. accept() 메소드는 매개값으로 T 객체 하나를 가지므로 람다식도 한 개의 매개 변수를 사용한다. 타입 파라미터 T에 String이 대입되었기 때문에 람다식 t 매개 변수 타입은 String이 된다.
Consumer<String> consumer = t -> { t를 소비하는 실행문; };
BiConsumer<T, U> 인터페이스를 타겟 타입으로 하는 람다식은 다음괌 같이 작성할 수 있다. accept() 메소드는 매개값으로 T와 U 두 개의 객체를 가지므로 람다식도 두 개의 매개 변수를 사용한다. 타입 파라미터 T와 U에 String이 대입되었기 때문에 람다식의 t와 u 매개 변수 타입은 각각 String이 된다.
BiConsumer<String, String> consumer = (t, u) -> { t와 u를 소비하는 실행문; }
DoubleConsumer 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. accep() 메소드는 매개값으로 double 하나를 가지므로 람다식도 한 개의 매개 변수를 사용한다. d는 고정적으로 double 타입이 된다.
DoubleConsumer consumer = d -> { d를 소비하는 실행문; }
ObjIntConsumer<T> 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. accep() 메소드는 매개값으로 T 객체와 int 값 두 개를 가지기 때문에 람다식도 두 개의 매개 변수를 사용한다. T가 String 타입이므로 람다식의 t 매개 변수 타입은 String이 되고, i는 고정적으로 int 타입이 된다.
ObjIntConsumer<String> consumer = (t, i) -> { t와 i를 소비하는 실행문; }
// ConsumerExample.java -- Consumer 함수적 인터페이스
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.ObjIntConsumer;
public class ConsumerExample {
public static void main(String[] args) {
Consumer<String> consumer = t -> System.out.println(t + "8");
consumer.accept("Hello");
BiConsumer<String, String> bigConsumer = (t, u) -> System.out.println(t + u);
bigConsumer.accep("Hello", "8");
DoublcConsumer doubleConsumer = d -> System.out.println("Hello" + d);
doubleConsumer.accept(8.0);
ObjIntConsumer<String> objIntConsumer = (t, i) -> System.out.println(t + i);
objIntConsumer.accept("Hello", 8);
}
}
'Java 길찾기 > 이것이 자바다' 카테고리의 다른 글
[Java] 표준 API의 함수적 인터페이스 - Operator, Predicate (0) | 2022.04.18 |
---|---|
[Java] 표준 API의 함수적 인터페이스 - Suplier, Function (0) | 2022.04.15 |
[Java] 클래스 멤버와 로컬 변수 사용 (0) | 2022.04.13 |
[Java] 타겟 타입과 함수적 인터페이스 (0) | 2022.04.12 |
[Java] 람다식 기본 문법 (0) | 2022.04.11 |