람다 표현식(Lambda Expressions)
함수형 프로그래밍(Functional Programming)은 하나의 새로은 프로그래밍 패러다임입니다. 함수형 프로그래밍은 기본적으로 람다대수(lambda calculus)에 그 근간을 두고 있는 개념으로 다수의 함수형 프로그래밍 언어들은 람다 연산을 발전시킨 것으로 볼 수 있습니다. 지난 몇 년간 함수형 프로그래밍은 가장 인기있고 중요한 프로그래밍 패러다임이 되었고 객체지향 언어인 자바 역시 이런 함수형 언어의 장점을 도입하게 됩니다.
함수형 언어의 가장 큰 특징 중 하나는 함수가 1급객체(First class object)로 취급된다는 점입니다. 1급객체는 변수나 데이터 구조 안에 담길 수 있고 파라미터나 반환값으로 사용가능한 객체를 말합니다. 우리가 알고 있는 고전적인 자바에서 메소드는 1급 객체(일급 시민)이 아니었습니다. 자바8의 설계자들은 이급 시민을 일급 시민으로 바꿀 수 있는 기능을 추가했습니다.
람다 표현식(lambda expressions)은 일급객체인 메서드를 전달 할 수 있는 익명 함수를 단순화 한 것이라고 할 수 있습니다. 람다 표현식은 파라미터, 화살표, 바디로 이루어지고 화살표를 기준으로 왼쪽에는 파라미터 리스트, 오른쪽에는 함수에 내용에 해당하는 바디가 위치하게 됩니다. 자세한 내용은 아래 코드를 통해 살펴보도록 하겠습니다.
public List<Student> getPreferStudent(List<Student> students) {
List<Student> result = new ArrayList<>();
for (Student student : students) {
if (student.score > 80) {
result.add(student);
}
}
return result;
}
위 코드는 학생 목록을 파라미터로 전달받고 그 중 점수가 80점 이상인 학생의 리스트를 만들어서 반환하는 메서드 입니다. 이 때 분기문 안에 조건을 파라미터로 전달 받는다고 생각해 보겠습니다.
public List<Student> getPreferStudent(List<Student> students, Checker c) {
List<Student> result = new ArrayList<>();
for (Student student : students) {
if (c.check(student)) {
result.add(student);
}
}
return result;
}
Checker 객체를 파라미터로 전달받고 check 라는 메서드를 호출합니다. 이를 위해서 Checker 를 구현한 객체가 있어야 합니다.
public interface Checker {
boolean check(Student student);
}
public class ScoreCheck implements Checker {
@Override
public boolean check(Student student) {
return student.score > 80;
}
}
먼저 check 라는 메소드 하나만 존재하는 Checker 라는 interface를 만들고 이를 구현한 클래스를 만듭니다.
Checker c = new ScoreCheck();
List<Student> results = test.getPreferStudent(students, c);
이 때, 메서드를 호출하는 부분에서는 Checker를 구현한 객체를 생성하고 파라미터로 넘겨줘야 합니다. 하지만 딱 한 번만 사용하는 메서드를 위해 클래스를 만드는 것은 조금 비효율 적으로 보입니다. 그래서 아래처럼 익명클래스를 이용해 보도록 하겠습니다.
List<Student> results = test.getPreferStudent(students, new Checker() {
@Override
public boolean check(Student student) {
return student.score > 80;
}
});
전에비해 단순해지긴 했지만 여전히 코드가 길어보입니다. 이 때 사용할 수 있는것이 바로 람다 표현식입니다.
List<Student> results = test.getPreferStudent(students, student -> student.score > 80);
람다표현식을 사용하자 복잡했던 코드가 한 줄에 정리 되는 것을 볼 수 있습니다.