✍️ Java에서 제공하는 함수형 인터페이스
public interface RunSomething {
abstract void doIt(); // abstract 키워드 생략 가능
}
함수형 인터페이스를 직접 정의하지 않아도 Java에서 기본으로 제공하는 함수형 인터페이스가 있다.
Java가 제공하는 함수형 인터페이스는 java.util.function 패키지에 포함되어 있다.
Function<T,R>
가장 대표적인 Function 함수형 인터페이스를 살펴보면, 입력이 하나 있고 반환값이 있는 추상 메서드를 하나 가지고 있다.
Interface Function<T,R> : Represents a function that accepts one argument and produces a result.
Type Parameters:
T - the type of the input to the function (입력의 타입)
R - the type of the result of the function (출력의 타입)
R apply(T t)
Function<T,R> 구현체 클래스를 이용한 구현 방법
public class Plus10 implements Function<Integer, Integer> {
@Override
public Integer apply(Integer value) {
return value + 10;
}
}
public class Test {
public static void main(String[] args) {
Plus10 plus10 = new Plus10();
int result = plus10.apply(20);
System.out.println(result);
}
}
// 30
Function<T,R> 람다 표현식을 통한 구현 방법
public class Test {
public static void main(String[] args) {
Function<Integer, Integer> plus10 = input -> input + 10;
int result = plus10.apply(20);
System.out.println(result);
}
}
// 30
compose, andThen
Function 인터페이스의 default 메서드인 compose와 andThen를 사용하면 두 함수형 인터페이스를 조합할 수 있다.
default <V> Function<T,V>andThen(Function<? super R,? extends V> after)
Returns a composed function that first applies this function to its input, and then applies the after function to the result.
default <V> Function<V,R>compose(Function<? super V,? extends T> before)
Returns a composed function that first applies the before function to its input, and then applies this function to the result.
여기 input에 10을 더하는 plus10과 input에 2를 곱하는 multiply2 구현 객체가 있다.
multiply2를 먼저 apply하고 다음으로 plus10을 apply하고 싶다면 다음과 같은 코드 순서로 구현할 수 있다.
public class Test {
public static void main(String[] args) {
Function<Integer, Integer> plus10 = input -> input + 10;
Function<Integer, Integer> multiply2 = input -> input * 2;
Function<Integer, Integer> multiply2AndPlus10 = plus10.compose(multiply2);
int result = multiply2AndPlus10.apply(3);
System.out.println(result);
}
}
// 16
반대로 plus10의 결과물에 multiply2를 하고 싶다면 다음과 같은 순서로 표현할 수 있다.
public class Test {
public static void main(String[] args) {
Function<Integer, Integer> plus10 = input -> input + 10;
Function<Integer, Integer> multiply2 = input -> input * 2;
Function<Integer, Integer> plus10AndMulitply2 = plus10.andThen(multiply2);
int result = plus10AndMulitply2.apply(3);
System.out.println(result);
}
}
// 26
🍊 그 외 기본 함수형 인터페이스
- BiFunction<T,U,R>
- 두 개의 값(T, U)를 받아서 R 타입을 반환하는 함수형 인터페이스
- R apply(T t, U u)
BiFunction<Integer, Integer, Integer> addTwoInt = (a, b) -> a + b;
int res = addTwoInt.apply(5, 10);
System.out.println(res);
// 15
- Consumer<T>
- T 타입을 받아서 아무 값도 리턴하지 않는 함수형 인터페이스
- void accept(T t)
- andThen
Consumer<Integer> printInt = input -> System.out.println(input);
printInt.accept(10);
// 10
- Supplier<T>
- T 타입의 값을 반환하는 함수형 인터페이스
- T get()
Supplier<Integer> get10 = () -> 10;
int res = get10.get();
System.out.println(res);
// 10
- Predicate<T>
- T 타입을 받아서 boolean을 반환하는 함수형 인터페이스
- boolean test(T t)
- and, or, negate
Predicate<String> startWithGang = str -> str.startsWith("gang");
boolean res = startWithGang.test("gangplank");
System.out.println("gangplank is start with gang : " + res);
Predicate<Integer> greaterThan10 = input -> input > 10;
res = greaterThan10.test(20);
System.out.println("20 is greater than 10 : " + res);
Predicate<Integer> lessThan100 = input -> input < 100;
res = greaterThan10.and(lessThan100).test(20);
System.out.println("20 > 10 and 20 < 100 : " + res);
// gangplank is start with gang : true
// 20 is greater than 10 : true
// 20 > 10 and 20 < 100 : true
- UnaryOperator<T>
- Function<T, R>의 특수한 형태로, 입력값 하나를 받아서 동일한 타입을 반환하는 함수형 인터페이스
Function<Integer, Integer> plus20F = input -> input + 20;
int res = plus20F.apply(10);
System.out.println(res);
UnaryOperator<Integer> plus20U = input -> input + 20;
res = plus20U.apply(10);
System.out.println(res);
// 30
// 30
- BinaryOperator<T>
- BiFunction<T, U, R>의 특수한 형태로, 동일한 타입의 입력값 두 개를 받아 동일한 타입을 반환하는 함수형 인터페이스
BiFunction<Integer, Integer, Integer> addTwoIntBF = (a, b) -> a + b;
int res = addTwoIntBF.apply(5, 10);
System.out.println(res);
BinaryOperator<Integer> addTwoIntBO = (a, b) -> a + b;
res = addTwoIntBO.apply(5, 10);
System.out.println(res);
// 15
// 15
'Java > Java 8' 카테고리의 다른 글
[Java8] Chapter 3-1. Stream API (1) (0) | 2022.02.18 |
---|---|
[Java8] Chapter 2-1. 인터페이스 default, static 메서드 (0) | 2022.02.17 |
[Java8] Chapter 1-4. 메서드 레퍼런스 (0) | 2022.02.16 |
[Java8] Chapter 1-3. 람다 표현식과 변수 캡쳐 (0) | 2022.02.08 |
[Java8] Chapter 1-1. 함수형 인터페이스와 람다 표현식 (0) | 2022.02.02 |