
Enum의 활용도를 공부하다 CALC_A(value -> value) 이런식으로 함수형 인터페이스가 사용될 수 있다는 사실을 알게었고, 함수형 인터페이스가 다양하게 활용될 수 있을 것 같은데 나는 기본적인 것도 잘 모르는 것 같아 이를 공부해야겠다는 생각이 들었다.
함수형 인터페이스란?
추상메서드 단 하나만 존재하는 인터페이스를 함수형 인터페이스라고 한다.
@FunctionalInterface
interface MyFunction{
public abstract int max(int a, int b); //public abstract 는 생략가능
}
이렇게 직접 만들 수 있으며 @FunctionalInterface 어노테이션이 필수적인건 아니지만, 이것을 붙여주면 추상메서드가 두 개 이상 들어가는 것 등의 오류를 컴파일러가 체크해준다.
직접 만들 수도 있지만 자바에서는 자주 사용하는 다양한 함수형 인터페이스를 제공한다.
java.util.function 패키지
기본 함수형 인터페이스 ( 매개변수 1)
- Runnable - 매개변수도 없고, 반환값도 없음 :
void run() - Supplier<T> - 매개변수는 없고, 반환값만 있음 :
T get() - Consumer<T> - 매개변수만 있고, 반환값이 없음(supplier 반대) :
void accept(T t) - Function<T,R> - 일반적인 함수, 하나의 매개변수를 받아서 결과를 반환 :
R apply(T t) - Predicate<T> - 조건식을 표현하는데 사용. 매개변수는 하나, 반환타입은 bool :
boolean test(T t)
사용 예시
Predicate<STring> imEmptyStr = s -> s.length()==0;
if (isEmptyStr.test(s)){
sout()
}
람다식에 붙여지는 이름이 run, get, test 등인 것이다.
매개변수가 2개인 함수형 인터페이스
- BiConsumer <T, U> :
void accept(T t, U u) - BiPredicate <T,U> :
boolean test(T t, U u) - BiFunction <T,U,R> :
R apply(T t, U u)
매개변수 3개인 함수형 인터페이스는 아래와 같이 직접 정의해야 한다.
@FunctionalInterface
interface TriFunction<T,U,V,R>{
R apply (T t, U u, V v);
}
매개변수의 타입과 반환 타입이 일치하는 함수형 인터페이스
- UnaryOperator<T> :
T apply(T t)- Function의 자손 - BinaryOperaor<T> :
T apply(T t, T t)- BiFunction의 자손
Function과 달리 매개변수와 결과의 타입이 같다
함수 결합 메서드
compose
compose()는()안의 연산을 먼저 실행 시킨 뒤, 해당 결과 값을 사용하는 메소드이다.
andThen
andThen()은compose()와 달리()안의 연산을 나중에 실행 시킨 뒤, 해당 결과 값을 사용하는 메소드이다.
사용예시
Function<String, Integer> f2 = (s2) -> Integer.parseInt(s2, 16); //16진수로 변환
Function<Integer, String> g = (i) -> Integer.toBinaryString(i); //2진수로 변환
Function<String, String> h = f2.andThen(g);
Function<Integer, Integer> h2 = f2.compose(g);
System.out.println(h.apply("FF")); // "F" → 255 → "11111111"
System.out.println(h2.apply(2)); // 2 → "10" → 16
compose는 g부터 실행하고 f2 실행, andThen은 f2부터 실행후 g를 실행한다.
Predicate의 결합
and(), or(), negate() 로 결합 가능하다.
사용예시
Function<String, String> f3 = x -> x; // 항등 함수(identity function)
System.out.println(f3.apply("AAA")); // AAA가 그대로 출력됨
Predicate<Integer> p2 = i -> i < 100;
Predicate<Integer> q = i -> i < 200;
Predicate<Integer> r = i -> i%2 == 0;
Predicate<Integer> notP = p2.negate(); // i >= 100
Predicate<Integer> all = notP.and(q).or(r);
System.out.println(all.test(150)); // true
String str1 = "abc";
String str2 = "abc";
// str1과 str2가 같은지 비교한 결과를 반환
Predicate<String> p3 = Predicate.isEqual(str1);
boolean result = p3.test(str2);
System.out.println(result);
예시를 보면 아마 바로 이해가 갈것이다. and, or은 익숙하고, negate가 !로 반대를 의미한다고 생각하면 된다.
'Java' 카테고리의 다른 글
| [ Java ] Checked Exception, Unchecked Exception (0) | 2022.12.04 |
|---|---|
| [Java] Optional (0) | 2022.12.02 |
| [ Java ] Enum (0) | 2022.11.23 |
| [Java] Arrays.asList 와 List.of (0) | 2022.11.17 |
| [Java] MultiValueMap이란 (0) | 2022.11.17 |