앞에서도 언급했듯이 자바는 객체지향형 언어이기 때문에 함수를 일급함수로 다루려면 인터페이스가 제공되어야 하는데 람다식을 다루기 위해 함수형 인터페이스는 단 하나의 추상 메서드만 선언된 함수형 인터페이스여야 한다.
즉, 함수형 인터페이스는 여러 개의 추상메소드를 가질 수 없다.
생성된 인터페이스가 함수형 인터페이스임을 명확히 하기 위해 인터페이스 상단에 @FunctionalInterface 애노테이션을 붙인다.
인터페이스 상단에 @FunctionalInterface 애노테이션을 반드시 붙여야 하는 것은 아니다.
그러나, 인터페이스가 람다식을 작성할 목적으로 만들어졌다면 그 의미를 명확히 하기 위해 애노테이션을 붙이는 것이 좋다.
인터페이스 상단에 @FunctionalInterface 애노테이션을 선언한 후 하나의 추상 메소드를 선언한다.
@FunctionalInterface
interface MyCalculator {
public int compare(int a, int b);
}
위에서 언급했 듯이 함수형 인터페이스에 둘 이상의 메소드가 선언될 경우는 오류이다.
아래의 @FunctionalInterface 를 머리에 이고 있는 MyCalculator 인터페이스에 even() 메소드를 선언하면
"Invalid '@FunctionalInterface' annotation; MyCalculator is not a functional interface"
라는 오류가 발생한다.
@FunctionalInterface
interface MyCalculator {
public int compare(int a, int b);
public boolean even(int a); // 오류
}
@FunctionalInterface로 선언된 인터페이스에 둘 이상의 메소드를 선언하고자 하면 추가된 메소드는 “default” 키워드를 붙이고 메소드의 body 부분을 정의해야 한다.
@FunctionalInterface
interface MyCalculator {
public int compare(int a, int b);
public default int add(int a, int b) {
return a + b;
}
}
public class TestLambda03 {
public static void main(String[] args) {
int a = 15, b = 10;
MyCalculator calc = (x, y) -> x - y; // 람다객체 정의
int result = calc.compare(a, b);
System.out.printf("%d가(이) %d보다 %S%n", a, b, (result < 0) ? "작다": "크다");
result = calc.add(a, b);
System.out.printf("%d + %d = %d%n", a, b, result);
}
}
MyCalculator 인터페이스 내의 compare() 메소드를 람다식으로 정의해보자
@FunctionalInterface
interface MyCalculator {
public int compare(int a, int b);
}
MyCalculator 인터페이스의 compare () 메소드는 두개의 정수형 값을 전달받아 비교하는 작업을 거친 후 그 결과를 다시 정수로 반환하는 메소드이다.
추상 메소드인 compare() 메소드를 정의하는 람다식은 아래의 순서로 만들 수 있다.
① 메소드의 접근지정자 public과 메소드 명 compare를 제거
(int a, int b) { return a – b; }
② 매개변수의 타입 제거, 매개변수가 하나일 때는 소괄호도 생략 가능
(a, b) { return a – b; }
③ 매개변수를 위한 닫히는 소괄호와 메소드 정의를 위해 열리는 중괄호 사이에 -> 삽입
(a, b) -> { return a – b; }
④ 메소드 정의부의 중괄호와 return문 제거
(a, b) -> a – b;
⑤ 정의된 메소드의 반환값을 이 메소드가 정의된 인터페이스 타입으로 받는다.
MyCalculator calc = (a, b) -> a – b;
⑥ 메소드명 이용하여 람다식 사용
int result = calc.compare(10, 15)
위의 공식(?)을 사용하여 매개 변수가 1개이고, boolean을 반환하는 람다식을 정의하고 사용하면 아래의 코드처럼 사용할 수 있다.
@FunctionalInterface
interface MyCalculator2 {
public boolean isEven(int a);
}
// 매개 변수가 1개일 경우 () 생략 가능
MyCalculator2 calc2 = x -> x % 2 == 0 ? true : false;
boolean bool = calc2.isEven(a);
System.out.printf("%d는 %s다%n", a, bool ? "짝수" : "홀수");
이번에는 매개 변수도 없고 반환값도 없는 람다식을 작성하는 코드를 살펴보자
@FunctionalInterface
interface MyCalculator3 {
public void output();
}
// 3) 매개변수가 없는 경우 () 생략 불가
// return이 없으므로 메소드 내부에서 실행할 문장 작성
MyCalculator3 calc3 = () -> System.out.println("매개변수도 반환값도 없음");
calc3.output();
람다식으로 정의될 메소드 내부의 코드가 아래와 같이 길 경우에는 {}도 생략할 수 없고, return 도 생략할 수 없다.
@FunctionalInterface
interface MyCalculator4 {
public double power(double a, int b);
}
// 함수의 정의부가 여러 줄일 때는 {}와 return 생략 불가
MyCalculator4 calc4 = (x, y) -> {
double r = 1;
for(int i=0; i<y; ++i) r *= x;
return r;
};
double c = 1.2;
System.out.printf("%.2f의 %d 거듭제곱 값은 %.5f다.%n", c, b, calc4.power(c, b));
여기까지 자바에서 람다식을 작성하는 기본적인 문법을 살펴보았다.
다음에는 이미 정의 되어있는 함수형 인터페이스 내의 추상메소드를 람다식으로 정의하는 방법을 보도록 하자.
이전글: 2. JDK 8에 추가된 주요 문법(Lambda)
다음글: 4. java.util.function 패키지에 정의된 Lambda
[Java] 4. java.util.function에 정의된 함수형 인터페이스 사용 (0) | 2023.08.08 |
---|---|
[Java] 2. JDK 8에 추가된 주요 문법(Lambda) (0) | 2023.08.03 |
[Java] 1. Java SE Version 변화 소개 (0) | 2023.08.03 |
댓글 영역