반응형
이전 포스팅에서 람다식(Lambda Expressions)에 대해서 간략하게 알아보았다.
이번 포스팅에서는 람다식과 밀접한 관련이 있는 함수형 인터페이스에 대해서 알아보도록 하자.
☕️ 함수형 인터페이스(Functional Interface)란?
함수형 인터페이스란 오로지 1개의 추상 메서드만을 갖는 인터페이스를 말한다.
(* Default Method와 Static Method의 개수는 상관이 없다.)
☕️ 함수형 인터페이스의 선언과 활용
함수형 인터페이스는 아래와 같은 형태로 만들 수 있다.
@FunctionalInterface
interface SquareIF {
int square(int num);
}
이때, 함수형 인터페이스를 나타내기 위해 @FunctionalInterface 어노테이션을 사용할 수 있다. 이 어노테이션을 사용하게 되면 만약 실수로 추상메서드를 추가하더라도 컴파일 시점에 오류를 확인할 수 있다.
따라서 함수형 인터페이스를 만들고자 할 때는 @FunctionalInterface 어노테이션을 적극 활용하는 것이 좋다.
이렇게 만들어진 함수형 인터페이스는 람다식을 사용하여 구현할 수 있게 된다.
@FunctionalInterface
interface SquareIF {
int square(int num);
}
public class Test {
public static void main(String[] args) {
SquareIF sif1 = (int a) -> {
return a * a;
};
System.out.println(sif1.square(2)); // 4
}
}
☕️ 자바에서 제공하는 함수형 인터페이스
함수형 인터페이스를 직접 만들어서 사용할 수도 있지만, 자바에서는 기본적으로 사용할 수 있는 다양한 함수형 인터페이스를 제공하고 있으며 대표적인 인터페이스는 다음과 같다.
- Consumer
- T타입 인자 하나를 받으며 리턴값은 없다. - Supplier
- 인자를 받지 않고 T타입을 반환한다. - Function
- T타입 인자를 받아서 R타입을 리턴한다. - Predicate
- T타입의 인자를 받아서 boolean 값을 반환한다.
Consumer 예제 코드
import java.text.DecimalFormat;
import java.util.function.*;
public class ConsumerEx {
public static void main(String[] args) {
// 한 개의 파라미터를 소비
Consumer<String> consumer = s -> System.out.println(s + " World!");
consumer.accept("Hello"); // Hello World!
// 두 개의 파라미터를 소비
BiConsumer<String, String> biConsumer = (t, u) -> System.out.println(t + " " + u);
biConsumer.accept("Hello", "World!"); // Hello World!
// double 값을 받아 소비
DoubleConsumer doubleConsumer = d -> System.out.println("num : " + d);
doubleConsumer.accept(10); // num : 10.0
// 객체와 int 값을 받아 소비
ObjIntConsumer<String> objIntConsumer = (t, u) -> System.out.println(t + u); // 객체, int 파라미터 소비
objIntConsumer.accept("num : ", 10); // num : 10
// int 값을 받아 소비(천 단위마다 콤마찍기 기능 추가)
IntConsumer intConsumer =
d -> {
DecimalFormat decFormat = new DecimalFormat("###,###");
System.out.println("num : " + decFormat.format(d));
};
intConsumer.accept(10000); // num : 10,000
}
}
Supplier 예제 코드
import java.util.Random;
import java.util.function.Supplier;
public class SupplierEx {
public static void main(String[] args) {
Supplier<Integer> randomNumbers = () -> new Random().nextInt(10);
System.out.println(randomNumbers.get()); // 0~9 사이의 랜덤한 값
}
}
Function 예제 코드
import java.util.function.Function;
public class FunctionEx {
public static void main(String[] args) {
Function<String, String> upperFunction = v -> v.toUpperCase();
String result = upperFunction.apply("abc");
System.out.println(result); // ABC
/* compose()와 andThen()
* 차이점 : 실행순서의 차이가 있다.
- compose
: A.compose(B);
: B실행 -> A실행
- andThen
: A.andThen(B);
: A실행 -> B실행
*/
System.out.println(upperFunction.compose(s -> "abc" + s).apply("d")); // ABCD
System.out.println(upperFunction.andThen(s -> "abc" + s).apply("d")); // abcD
}
}
Predicate 예제 코드
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class PredicateEx {
public static void main(String[] args) {
// 빈 문자인지 비교하여 제거
List<String> list = Arrays.asList("Java", "C", "", "Python", "", "Kotlin");
Predicate<String> noneEmptyStringPredicate = s -> !s.isEmpty();
for (String s : list) {
boolean result = noneEmptyStringPredicate.test(s);
if (result) {
System.out.println(s);
/* 출력결과
Java
C
Python
Kotlin
*/
}
}
// Stream의 filter()에 인자로 전달
list.stream().filter(noneEmptyStringPredicate).forEach(System.out::println);
/* 출력결과
Java
C
Python
Kotlin
*/
/*
AND연산 및 OR연산
- Predicate의 결과를 AND 연산하거나 OR 연산할 수 있습니다.
*/
Predicate<Integer> cond1 = (num) -> num > 10;
Predicate<Integer> cond2 = (num) -> num > 20;
boolean result;
// AND연산
result = cond1.and(cond2).test(15);
System.out.println(result); // false
// OR연산
result = cond1.or(cond2).test(15);
System.out.println(result); // true
/*
isEquals 연산
- 인자로 전달된 객체와 같은지 확인한다.
*/
String str1 = new String("abc");
String str2 = new String("abc");
Predicate<String> IsEqualPredicate = Predicate.isEqual(str1);
System.out.println(IsEqualPredicate.test(str2)); // true
}
}
References.
1. 뱀귤 - Java 8 함수형 인터페이스 (Functional Interface)
2. Catsbi's DLog - 함수형 인터페이스와 람다
3. DevStory - [Java]함수형 인터페이스(Functional Interface)
반응형
'Java' 카테고리의 다른 글
[Java] 스트림 API(Stream API) (0) | 2023.08.19 |
---|---|
[Java] 메서드 참조(Method Reference) (0) | 2023.08.16 |
[Java] Set과 equals() 및 hashCode()의 관계 (0) | 2023.08.13 |
[Java] 람다식(Lambda Expressions) (0) | 2023.08.08 |
[Java] 컬렉션 프레임워크(Collection Framework) (0) | 2023.08.07 |