본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



함수형 인터페이스란 ?


잘 알고 있듯이 Runnable 인터페이스는 run() 이라는 추상 메서드 하나만 가진다. 이처럼 추상 메서드 하나만 갖는 인터페이스를 자바 8부터는 함수형 인터페이스라고 한다. 이런 함수형 인터페이스만을 람다식으로 변경할 수 있다.


아래 함수형 인터페이스 TestFunctionInterface를 만들었는데 위에 @FunctionInterface 어노테이션을 붙이는 것은 옵션이다. 이 어노테이션이 붙을 경우 컴파일러는 인터페이스가 함수형 인터페이스의 조건에 맞는지 검사한다. 즉 단 하나의 추상 메서드만을 갖고 있는지 확인한다.


1
2
3
4
5
6
7
8
9
10
11
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = (int count) -> {return count * count;};
        System.out.println(tfi.runSomething(5)); //25
    }
}
 
@FunctionalInterface
interface TestFunctionInterface {
    public abstract int runSomething(int count);
}



위의 예제를 좀 더 간소화할 방법이 없나 고민해보자면. 먼저 람다식의 인자로 사용하고 있는 int count 부분을 보면 count는 int 자료형일 수밖에 없는 runSomething() 메서드 정의에서 알 수 있다. 따라서 int를 생략할 수 있다. 이를 타입 추정 기능이라고 한다.


1
2
3
4
5
6
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = (count) -> {return count * count;};
        System.out.println(tfi.runSomething(5)); //25
    }
}



소괄호가 거슬린다. 람다 설계자들은 인자가 하나이고 자료형을 표기 하지 않는 경우 소괄호를 생략해도 되게끔 만들었다.


1
2
3
4
5
6
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = count -> {return count * count;};
        System.out.println(tfi.runSomething(5)); //25
    }
}



part 1에서 얘기한 대로 코드가 1줄일 경우에는 중괄호 {}를 생략할 수 있다. 다만 이때 return 구문도 생략해야 한다. 역시 runSomething 메서드 정의를 통해 int가 반환된다는 사실을 알 수 있기에 return을 생략해도 무방하다. 그리고 연산식 뒤에 세미콜론도 없애야 한다.


1
2
3
4
5
6
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = count -> count * count;
        System.out.println(tfi.runSomething(5)); //25
    }
}



메서드 호출 인자로 람다 사용


위의 예제들은 람다식을 함수형 인터페이스의 참조 변수에 저장해서 사용했다. 람다식을 변수에 저장하는 것이 가능하다면 당연히 메서드의 인자로도 사용할 수 있다. 코드 블록을 메서드의 인자로 전달할 수 있는 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = count -> count * count;
        
        doIt(tfi, 5);
    }
    
    public static void doIt(TestFunctionInterface tfi, int value) {
        int result = tfi.runSomething(value);
        
        System.out.println(result);
    }
}
 
@FunctionalInterface
interface TestFunctionInterface {
    public abstract int runSomething(int count);
}
 



람다식을 단 한번만 사용한다면 변수에 할당할 필요도 없이 아래와 같이 사용할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class LambdaTest {
    public static void main(String[] args) {
        doIt(count -> count * count, 5);
    }
    
    public static void doIt(TestFunctionInterface tfi, int value) {
        int result = tfi.runSomething(value);
        
        System.out.println(result);
    }
}
 
@FunctionalInterface
interface TestFunctionInterface {
    public abstract int runSomething(int count);
}



메서드 반환값으로 람다 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class LambdaTest {
    public static void main(String[] args) {
        TestFunctionInterface tfi = todo();
        int result = tfi.runSomething(5);
        
        System.out.println(result);
    }
    
    public static TestFunctionInterface todo() {
        return num -> num * num;
    }
}
 
@FunctionalInterface
interface TestFunctionInterface {
    public abstract int runSomething(int count);
}