ArrayList의 forEach, removeIf, sort 메소드 등 많은 곳에서 FunctionalInterface를 매개변수로 받고 있다. FunctionalInterface는 무엇인지 람다식은 무엇인지 알아보자.
FunctionalInterface란?
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/FunctionalInterface.html 에서 보면, 디폴트 메소드를 제외한 abstract method가 하나인 인터페이스라고 말한다.
인터페이스 위에 @FunctionalInterface 어노테이션을 사용하는데, 이 어노테이션을 사용하면 인터페이스가 FunctionalInterface의 조건에 맞는지 컴파일러가 확인해준다. 어노테이션을 붙이지 않아도 동작에 상관이 없지만, 잘못될 경우가 있으니 사용하는 것이 좋다.
커스텀 FunctionalInterface 예시)
class Main {
public static void main(String[] args) {
Sum s = (a, b) -> (a + b);
for (int i = 0; i < 10; i++) {
System.err.println(s.oneMethod(i, 2));
}
}
@FunctionalInterface
public interface Sum {
int oneMethod(int a, int b);
}
}
FunctionalInterface는 lambda expression과 method reference의 타깃이다. 그렇다면 lambda expression과 method reference는 무엇인가?
Lambda expression
람다식은 Java8에 추가된 것으로 간단한 코드 블럭이다.
Lambda 문법
() -> {code block}
(parameter1) -> {code block}
(parameter1, parameter2) -> {code block}
() -> expression
(parameter1) -> expression
(parameter1, parameter2) -> expression
parameter1 -> expression
parameter1 -> {code block}
()안에 매개변수를 넣으며, 매개변수가 1개일 경우에만 괄호를 생략할 수 있다.
중간에 ->가 있다.
{}에 code block을 넣을 수 있다. 괄호를 생략할 경우에는 expression 값이 반환된다. 생략한다면 변수, 할당, 조건문, 반복문을 사용하지 못하며 즉시 값을 반환해야 한다.
lambda expression의 타겟은 FunctionalInterface여야만 한다.
예시)
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
Sum s = (a, b) -> (a + b);
for (int i = 0; i < 10; i++) {
arr.add(s.get(i, 2));
}
arr.forEach((n) -> {
for (int i = 0; i < n; i++)
System.out.print('*');
System.err.println();
});
}
@FunctionalInterface
public interface Sum {
int get(int a, int b);
}
}
출력:
**
***
****
*****
******
*******
********
*********
**********
***********
Method reference
메소드 참조는 메소드를 FunctionalInterface로 반환하는 방법이다. 일반 메소드, static 메소드, 생성자를 참조할 수 있으며 클래스이름::메소드이름 으로 참조한다.
이때 FunctionalInterface의 매개변수 타입 == 메소드의 매개변수타입, FunctionalInterface의 매개변수 개수 == 메소드의 매개변수 개수, 함수형 인터페이스의 반환형 == 메소드의 반환형 3가지 조건을 만족시켜야 한다.
예시)
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
Sum s = (a, b) -> (a + b);
for (int i = 0; i < 10; i++) {
arr.add(s.get(i, 2));
}
arr.forEach(System.out::println);
}
@FunctionalInterface
public interface Sum {
int get(int a, int b);
}
}
출력:
2
3
4
5
6
7
8
9
10
11
java.util.function
JDK에서 사용되는 일반적인 목적의 함수형 인터페이스의 모음 package이다. ArrayList, ArrayDeque, LinkedList 등에서 사용된다.
4가지 기본적인 함수형 인터페이스가 있다.
인터페이스 | 설명 |
Supplier<T> | 매개변수 없이 반환값만 있다 |
Consumer<T> | 단항의 매개변수를 받고 반환값이 없다 |
Predicate<T> | 단항의 매개변수를 받고 Boolean을 반환한다 |
Function<T, R> | 단항의 매개변수를 받아 처리후 R로 반환한다 |
위 인터페이스 외에 Bi가 붙은 인터페이스(BiConsumer, BiPredicate, BiFunction 등)는 2항의 매개변수를 받는 인터페이스이다.
참고: https://mangkyu.tistory.com/113
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/FunctionalInterface.html
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/function/package-summary.html
https://mangkyu.tistory.com/113
-
'Java' 카테고리의 다른 글
Java annotation (0) | 2024.10.29 |
---|---|
Java concurrent programming (0) | 2024.09.27 |
Java 파일 조작 (File Handling) (0) | 2024.09.23 |
Java 예외 처리 (Exception, try catch) (1) | 2024.09.21 |
Java Regular Expressions (정규 표현식) (0) | 2024.09.20 |