프로그래밍 언어/자바(JAVA)

자바(JAVA) - 람다식(Lambda Expression)

나아가는중 2022. 1. 21. 18:34
반응형

람다식(Lambda Expression)

람다식은 자바에서 제공하는 함수형 프로그래밍(Functional Programming) 방식입니다. 자바의 객체지향 프로그래밍(Object Oriented Programming) 이지만, JDK 1.8 Java 8)부터 함수형 프로그래밍 기능을 추가하였습니다.

 

람다식은 익명 함수(Anonymous functions)를 지칭하는 용어로 함수(메서드)를 간단한 식(expression)으로 표현하는 방법입니다. 하지만 자바에서 람다식은 익명 함수가 아니라 익명 객체입니다. 자바에서는 함수만 존재할 수 없으므로 객체 형식으로 존재해야합니다.

 

본래는 익명 객체를 사용하는 것을 람다식을 사용하여 표현할 수 있습니다.

 

익명 객체란 이름이 없는 일회용 클래스로 선언과 생성을 동시에 합니다. 자세한 내용은 아래 글을 참조해주세요.

https://dlee0129.tistory.com/231

 

자바(JAVA) - 익명 클래스 (Anonymous class)

익명 클래스란 이름이 없는 일회용 클래스입니다. 일회용으로만 사용하기 때문에 이름이 필요 없으며 객체 생성 시에 클래스 정의와 생성을 동시에 합니다. 보통의 자바 클래스는 클래스를 정

dlee0129.tistory.com

 

 

하지만, 익명 객체를 다음과 같이 만들어 사용하려 하면 max 메서드를 찾을 수 없다고 오류가 발생합니다. 익명 객체가 상속받은 Object 클래스는 max() 메서드를 가지고 있지 않기 때문에 오류가 발생합니다.

public class Lambda {
    public static void main(String[] args) {
        Object obj = new Object() {
            int max(int a, int b) {
                return a > b ? a : b;
            }
        };

        System.out.println(obj.max(3, 5));
    }
}

 

 

익명 객체를 사용하려면 함수형 인터페이스를 사용해야 합니다.

 

함수형 인터페이스는 하나의 추상 메서드만 선언되어 있는 인터페이스를 말합니다.

람다식을 다루기 위한 인터페이스로 람다와 같이 jdk 1.8(java 8)부터 추가되었습니다.

 

인터페이스 타입의 참조변수로 람다식을 참조할 수 있습니다.

함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환타입이 일치해야 합니다.

 

어노테이션으로 @FunctionalInterface를 사용합니다.

 

다음과 같이 익명 클래스를 MyFunctionalInterface 함수형 인터페이스의 max() 메서드를 구현하여 사용할 수 있습니다.

public class Lambda {
    public static void main(String[] args) {
        MyFunctionalInterface obj = new MyFunctionalInterface() {
            @Override
            public int max(int a, int b) {
                return a > b ? a : b;
            }
        };

        System.out.println(obj.max(3, 5));
    }
}

@FunctionalInterface
interface MyFunctionalInterface {
    int max(int a, int b);
}

그리고 이는 다음과 같이 람다식으로 변경이 가능합니다.

public class Lambda {
    public static void main(String[] args) {
        MyFunctionalInterface obj = (a, b) -> a > b ? a : b;

        System.out.println(obj.max(3, 5));
    }
}

@FunctionalInterface
interface MyFunctionalInterface {
    int max(int a, int b);
}

 

 

 

학생 클래스 배열을 학생의 나이순으로 정렬하는 예제입니다.

 

여기에서 사용되는 Comparator는 함수형 인터페이스입니다.

레퍼런스를 보면 @FunctionalInterface라고 어노테이션이 붙어 있으며 하나의 추상 메서드(compare)만 존재합니다.

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    
    ...
}

 

 

익명 객체를 사용하여 Comparator 인터페이스를 구현한 것을 람다식으로 다음과 같이 변경 할 수 있습니다.

public class Lambda {
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student(17, 'M');
        students[1] = new Student(18, 'F');
        students[2] = new Student(20, 'M');

        // 익명 객체 사용
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.age - o2.age;
            }
        });

        // 람다식 사용
        Arrays.sort(students, (o1, o2) -> o1.age - o2.age);

        for (Student student : students) {
            System.out.println(student.age);
        }
    }
}

class Student {
    int age;
    char sex;

    public Student(int age, char sex) {
        this.age = age;
        this.sex = sex;
    }
}

 

반응형