함수형 인터페이스란 ?
잘 알고 있듯이 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); } |
'Java 개발 이야기' 카테고리의 다른 글
자바 synchronized에 대하여 (0) | 2018.11.24 |
---|---|
자바 쓰레드(Thread)에 대하여 (0) | 2018.11.24 |
자바 람다와 함수형 인터페이스 - part1 (0) | 2018.10.21 |
자바 Clone에 대해서 (0) | 2018.10.04 |
Oracle JDK와 Open JDK의 차이점 (0) | 2018.10.04 |