- 자바에서 FunctionalInterface와 람다 표현식의 개념을 이해하는 것은 함수형 프로그래밍을 효과적으로 사용하는 데 매우 중요합니다.
FunctionalInterface란 무엇인가?
- @FunctionalInterface는 자바에서 단 하나의 추상 메서드를 갖는 인터페이스를 나타내는 어노테이션입니다. 이 인터페이스는 람다 표현식, 메서드 참조와 함께 사용될 수 있습니다.
@FunctionalInterface
public interface BinaryOp {
public int apply(int a, int b);
}
- 이 인터페이스는 두 개의 정수를 받아서 하나의 정수 결과를 반환하는 apply라는 메서드를 정의합니다.
1. 클래스를 구현하여 사용
- 가장 전통적인 방식은 BinaryOp 인터페이스를 구현한 클래스를 작성하고, 그 클래스의 인스턴스를 사용하여 메서드를 호출하는 것입니다.
class Adder implements BinaryOp {
public int apply(int a, int b) {
return a + b;
}
}
class Test4 {
public static void main(String[] args) {
BinaryOp b = new Adder();
System.out.println(b.apply(1, 2));
}
}
- 이 방법은 코드가 명확하지만, 단순한 작업에 대해서는 다소 번거로울 수 있습니다.
2. 익명 클래스를 사용하여 구현
- 클래스를 별도로 정의하지 않고, BinaryOp 인터페이스를 익명 클래스로 구현할 수 있습니다.
- 이 방법은 클래스 선언을 줄일 수 있지만, 여전히 코드가 장황할 수 있습니다.
class Test4 {
public static void main(String[] args) {
BinaryOp b = new BinaryOp() {
public int apply(int a, int b) {
return a + b;
}
};
System.out.println(b.apply(1, 2));
}
}
- 익명 클래스는 클래스가 필요 없는 일회성 작업에 유용합니다.
3. 람다 표현식을 사용
- 람다 표현식을 사용하면 코드를 더 간결하게 만들 수 있습니다. 자바 8 이상에서 지원되며, 인터페이스의 유일한 메서드를 간단히 구현할 수 있습니다.
class Test4 {
public static void main(String[] args) {
BinaryOp b = (int x, int y) -> { return x + y; };
System.out.println(b.apply(1, 2));
}
}
- 람다 표현식은 특히 코드가 간단한 경우 강력합니다. 다음과 같이 더욱 간결하게 표현할 수 있습니다:
class Test4 {
public static void main(String[] args) {
BinaryOp b = (x, y) -> x + y;
System.out.println(b.apply(1, 2));
}
}
4. 메서드 참조를 사용
- 메서드 참조를 사용하면 이미 존재하는 메서드를 람다 표현식 대신 사용할 수 있습니다.
- 이 방법은 메서드의 이름을 그대로 사용할 수 있어서 가독성이 좋아집니다.
class Something {
public static int doSomething(int i, int j) {
System.out.println(i + j);
return 10;
}
}
class Test4 {
public static void main(String[] args) {
BinaryOp b = Something::doSomething;
b.apply(1, 2);
}
}
- 여기서 Something::doSomething은 doSomething 메서드를 BinaryOp의 apply 메서드로 사용할 수 있도록 연결합니다.
요약
- 클래스 구현: 명확하지만 다소 장황.
- 익명 클래스: 클래스 없이도 구현 가능하지만 코드가 길어질 수 있음.
- 람다 표현식: 간결하고 효과적이며, 함수형 인터페이스에 적합.
- 메서드 참조: 이미 정의된 메서드를 재사용할 수 있어 가독성 향상.
- 람다 표현식과 메서드 참조는 자바에서 함수형 프로그래밍 스타일을 구현하는 데 매우 유용합니다.
- FunctionalInterface는 이러한 기능을 활용하기 위한 기초입니다.