함수형 인터페이스란?
오직 하나의 추상메서드만 갖는 인터페이스
디폴트 메소드가 있더라도 추상메서드가 오직 하나면 함수형 인터페이스이다.
(예시)
public interface CustomFuntionalInterface {
int customFunction(int a, int b);
}
@FunctionalInterface
함수형 인터페이스임을 나타내는 어노테이션이다.
@FunctionalInterface로 인터페이스를 선언했지만 실제로 함수형 인터페이스가 아니면 컴파일러가 예외를 발생시킨다.
추상 메소드가 1개 이상이라면 컴파일 에러가 발생하는 것이다.
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
함수형 인터페이스의 종류
아래 코드에서는 추상 메소드만 나타내었으니 참고 바랍니다.
1. Predicate<T> (T → boolean)
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
T의 객체를 받아 boolean을 반환하는 추상메소드를 갖는다.
위의 Predicate<T> 인터페이스는 참조형(Byte, Integer, String 등) 파라미터만 전달할 수 있다.
다만 자바에서 기본형을 참조형으로 변환하는 오토박싱을 지원한다. 하지만 오토박싱은 메모리 비용이 추가적으로 발생한다.
아래 IntPredicate에서는 int를 Integer로 변환하는 오토박싱 없이 함수형 인터페이스를 구현할 수 있다.
* IntPredicate
@FunctionalInterface
public interface IntPredicate {
boolean test(int value);
}
IntPredicate 이외에도 LongPredicate, DoublePredicate도 지원을 한다.
2. Consumer<T> (T -> void)
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
T의 객체를 받아 void를 반환하는 추상메소드를 갖는다. 특정 객체를 인수로 받아 어떠한 동작을 수행하고 싶을 때 주로 사용한다.
3. Supplier<T> (void -> T)
@FunctionalInterface
public interface Supplier<T> {
T get();
}
아무런 인자도 전달받지 않고 특정 객체를 반환하는 추상메소드를 갖는다.
4. Function<T, R> (T -> R)
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
제네릭 형식의 T를 전달 받아서 제네릭 형식의 R을 반환하는 추상메소드를 갖는다. 특정 값을 넣으면 무조건 어떠한 값을 반환하는 함수의 특징을 갖는다고 생각하면 된다.
5. UnaryOperator<T> (T → T)
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
}
Function을 상속받으며, 전달받은 인자의 타입과 반환의 타입이 동일하다.
6. BinaryOperator<T> ((T, T) → T)
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
}
BiFunction을 상속받으며, 인자를 2개 전달받는다. 전달받는 인자들의 타입과 반환의 타입이 동일하다.
7. BiPredicate<L, R> ((L, R) → boolean)
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
}
인자를 전달받아 boolean을 반환한다는 점에서 Predicate와 비슷하다. 하지만 BiPredicate는 인자를 2개 전달받는 점이 특징이다.
8. BiConsumer<T, U> ((T, U) → void)
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
}
인자를 전달받아 void를 반환한다는 점에서 Consumer와 비슷하다. 하지만 BiConsumer는 인자를 2개 전달받는 점이 특징이다.
9. BiFunction<T, U, R> ((T, U) → R)
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
인자를 전달받아 특정 객체를 반환한다는 점에서 Function과 비슷하다. 하지만 BiFunction은 인자를 2개 전달받는 점이 특징이다.
람다로 구현하기
public static void consumerTest(List<Integer> numbers, Consumer<Integer> consumer) {
for(Integer number: numbers) {
if(consumer.test(number)) {
// ..
}
}
}
public static void main(String[] args) {
consumerTest(List.of(1, 2, 3), (number) -> number % 2 == 0);
}
'개발 > 자바' 카테고리의 다른 글
Java Closure (0) | 2022.12.03 |
---|---|
기본형 특화 스트림(IntStream, LongStream, DoubleStream) (3) | 2022.10.09 |
추상화란? (2) | 2022.03.17 |
compareTo()가 0을 반환하면 어떤 순서로 정렬되나? (0) | 2022.02.19 |
Java Stream.max() 사용법 (0) | 2022.02.14 |
이전 댓글