//메서드
int max(int a, int b){
return a > b ? a : b;
}
//'익명 함수'인 람다식을 작성하기 위해 메서드의 이름과 반환 타입을 지우고, '->'을 추가한다
//반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능
(int a, int b) -> a > b ? a : b
//매개변수의 타입이 추론 가능하면 생략가능
(a, b) -> a > b ? a : b
//매개변수가 하나이면 ()생략 가능, 단 타입을 지정하면 생략 불가
a -> a * 10
(long a) -> a * 10
예시
// 1.
int max(int a, int b){
return a > b ? a : b;
}
//람다로 변환
(a, b) -> a > b ? a : b
// 2.
int printVar(String name, int i){
System.out.println(name + "="+i);
}
//람다로 변환
(name, i) -> System.out.println(name + "="+i)
// 3.
int square (int x){
return x * x;
}
//람다로 변환
x -> x * x
// 4.
int roll(){
return (int)(Math.random()*6);
}
//람다로 변환
() -> (int)(Math.random()*6)
람다식은 익명 함수라고 했지만, 사실은 익명 객체이다
Class로 이루어진 Java의 특성처럼, 람다로 사용되는 메서드 또한 하나의 객체(Class)에 존재하는 메서드 중의 하나라는 뜻.
(a, b) -> a > b ? a : b
위 람다는,
new Object(){
int max(int a, int b){
return a > b ? a: b;
}
}
이 코드와 동일한 것이다.
이 람다식을 다루기 위해선 참조변수가 필요하다.
하지만, 위 코드를 고려하여 Object타입으로 참조변수를 생성하면, 오류가 발생한다.
Object obj = new Object(){
int max(int a, int b){
return a > b ? a: b;
}
}
// int value = obj.max(3,5);
// ERROR
obj
라는 참조변수는 Object
타입인데, 이 타입은 .max
라는 메서드가 존재하지 않기 때문이다.
이 람다를 다루기 위해선, 람다가 가지고 있는 메서드(max
)를 가진 인터페이스를 구현하는 클래스타입으로 참조변수를 만들어 사용한다.
@FunctionalInterface
interface MyFunction {
int max(int a, int b);
}
/*
MyFunction obj = new MyFunction(){
public int max(int a, int b){
return a > b ? a: b;
}
}
*/
MyFunction obj = (a, b) -> a > b ? a : b;
int value = obj.max(3,5); // 5
//클래스 선언과 객체 생성을 동시에 하며 MyFunction을 구현함
위 코드의 MyFunction
처럼 단 하나의 추상메서드만 선언된 인터페이스를 함수형 인터페이스
라고 한다. 이처럼 obj
를 통해 익명함수를 다룰 수 있다.
함수형 인터페이스를 선언할 땐, 애너테이션을 통해 함수형 인터페이스임을 알리는 것이 권장된다.
@FunctionalInterface
interface MyFunction {
void myMethod();
}
public class playGround{
public static void play() {
MyFunction f1 = () -> System.out.println("Hello");
MyFunction f2 = () -> System.out.println("World");
aMethod(f1);
aMethod(f2);
}
private static void aMethod(MyFunction f){
f.myMethod();
}
}
// Hello
// World
aMethod()
는 함수형 인터페이스 MyFunction
타입을 매개변수로 받는다.
MyFunction
타입의 f1
, f2
에 해당하는 람다식을 받아 실행한다.