다음과 같은 class 가 있습니다.
아래같은 리스트가 있습니다. 그런데 사과만 보고싶다고 합니다.
아래처럼 구현했습니다.
바나나만 보고싶다고 해도 똑같겠죠 ? 중복이 되지않게 파라미터를 받는방법으로 수정합니다.
하지만 아래에 대한 요구사항을 구현할 땐 어떨까요 ? 파라미터를 늘리는 것으로 커버하긴 힘들겠죠? 그렇다고 메소드를 만들수도없구요.
인터페이스와 익명 클래스를 사용해서 무수한 메소드생성을 막을 수 있습니다.
하지만 ‘익명 클래스’를 사용하는 것은 복잡합니다.
과일 간의 무게 비교를 한다거나, N개의 과일을 한 번에 비교한다거나 등등.. 다양한 Filter가 필요할 수도 있습니다.
따라서 JDK8부터 람다 (이름이 없는 함수) 등장 하였습니다.
FruitFilter와 같은 인터페이스 Predicate, Consumer 등을 많이 만들어 두었다.
또한 간결한 스트림이 등장했다.
‘메소드 자체를 직접 넘겨주는 것처럼’ 쓸 수 있다
사실 이말은 즉 바꿔 말하면, Java에서 함수는 변수에 할당되거나 파라미터로 전달할 수 없다.
Java와는 근본적으로 다른 한 가지가 있다.
코틀린에서는 함수가 그 자체로 값이 될 수 있다. 변수에 할당할수도, 파라미터로 넘길 수도 있다.
다음은 호출하는 방법이다.
함수의 타입 : (파라미터 타입...) → 반환 타입
위에 자바에서 했던 코드를 코틀린으로 작성해보겠습니다.
Kotlin에서는 함수가 1급 시민이다. (Java에서는 2급 시민)
마지막 파라미터가 함수인 경우, 소괄호 밖에 람다 사용 가능
람다를 작성할때, 람다의 파라미터를 it 으로 직접 참조할 수 있다.
람다를 여러줄 작성할 수 있고, 마지막 줄의 결과가 람다의 반환값이다.
아래 자바 코드에선 왜 에러가 날까요 ?
Variable used in lambda expression should be final or effectively final
Java에서는 람다를 쓸 때 사용할 수 있는 변수에 제약이 있습니다. 위의 경우는 바나나 였다가 수박으로 변경되어서 에러가 발생했습니다.
하지만 코틀린에서는 아무런 문제 없이 동작합니다.
어떻게 이것이 가능할까 ?
코틀린에서는 람다가 시작하는 지점에 참조하고 있는 변수들을 모두 포획하여 그 정보를 가지고 있다.
이렇게 해야만, 람다를 진정한 일급 시민으로 간주할 수 있다. 이 데이터 구조를 Closure라고 부른다.
다음 포스팅에서는 컬렉션을 함수형으로 다루는 방법에 대해 공부해보겠습니다.