ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java - 람다식의 개념과 사용 방법
    Language/Java 2022. 11. 29. 21:32

    람다식의 개념과 사용 방법

    람다식이란?

    람다식은 메서드를 하나의 식으로 표현한 것을 말한다. 그리고 람다식은 함수의 이름이 없기 때문에 익명 함수라 도고 한다.

    또한, 람다식은 메서드의 매개변수로 메서드의 결과로 반환될 수 있는 특징이 있어서 함수를 변수로 다룰 수 있다는 장점이 있다.

     

    람다식의 기본 문법
    A a - (매개변수) -> {구현코드};

    람다식을 작성하는 방법은 위와 같다.

     

    왼쪽 소괄호 안의 매개변수는 오른쪽 중괄호 블록을 실행하기 위해 필요한 값을 제공하는 역할을 하며, 주어진 매개변수를 이용해서 중괄호 블록을 실행한다고 보면 된다.

     

    람다식의 적용 예

    Runnable runnable  = new Runnable() {
        public void run() {
            System.out.println("Lamda");
        }
    };

    위 코드는 람다식을 적용하지 않고 Runnable 인터페이스를 구현한 코드이다.

     

    Runnable runnable = () -> {
        System.out.println("Lamda");    
    };

    람다식을 적용하면 위와 같이 소스코드를 작성할 수 있다.

     

    일반적으로 자바에서 메서드를 작성하기 위해서는 접근 제한자, static의 유무, 리턴 타입, 메서드 이름, 매개 변수를 적어 주어야 하는데, 람다식을 사용하면 짧은 코드를 통해서 표현이 가능하다. 그리고 이것이 바로 람다식의 최대 장점이다.

     

    타겟 타입

    위의 예시를 보면, 람다식의 형태는 매개 변수를 가진 코드 블록이므로 마치 자바의 메서드를 선언하는 것처럼 보인다.

    자바에서는 메서드를 단독으로 선언할 수 없고 항상 클래스의 구성 멤버로 선언해야 한다. 하지만, 람다식은 단순히 메서드를 선언하는 것이 아니라 이 메서드를 가지고 있는 객체를 생성해 낸다.

     

    그리고 이 객체의 타입은 다름 아닌 인터페이스이다. "인터페이스 변수 = 람다식;"과 같이 선언하는 것이다.

    즉, 람다식은 인터페이스의 익명 구현 객체를 생성한다는 뜻이다.

     

    인터페이스는 직접 객체화할 수 없기 때문에 구현 클래스가 필요한데, 람다식은 익명 구현 클래스를 생성하고 객체화한다. 또한, 람다식은 대입될 인터페이스의 종류에 따라 작성 방법이 달라지기 때문에 람다식이 대입될 인터페이스를 람다식의 타겟 타입이라고 부른다.

     

    함수적 인터페이스

    그렇다면, 모든 인터페이스를 람다식의 타겟 타입으로 사용할 수 있을까? 아니다. 람다식은 하나의 메서드를 정의하기 때문에 두 개 이상의 추상 메서드가 선언된 인터페이스는 람다식을 이용해서 구현 객체를 생성할 수 없다.

    따라서, 하나의 추상 메서드가 선언된 인터페이스만이 람다식의 타겟 타입이 될 수 있는데, 이러한 인터페이스를 함수적 인터페이스라고 부른다.

     

    @FunctionalInterface
    public interface MyFunctionalInterface {
        public void sum();
    }

    위 코드는 함수적 인터페이스를 정의하는 코드이다.

     

    선언 방식은 우리가 원래 알고 있는 인터페이스의 형식과 크게 다르지 않다.

    위에 "@FunctionalInterface" 애너테이션은 함수적 인터페이스를 작성할 때 두 개 이상의 추상 메서드가 선언되지 않도록 컴파일러가 체킹 해주는 기능이다. 만약, 추상 메서드가 두 개 이상이 선언될 경우 컴파일 에러가 발생한다.


    람다식 작성

    1. 매개변수가 없고, 리턴 값이 없는 람다식
    @FunctionalInterface
    public interface MyFunctionalInterface {
        public void sum();
    }

    위에서 설명한 람다식의 기본 문법과 함수적 인터페이스를 사용한 예제를 살펴보겠다. 여기서 함수적 인터페이스는 위에서 정의한 MyFunctionalInterface를 사용한다.

     

    public class Main {
        public static void main(String[] args) {
            // 객체 선언
            MyFunctionalInterface mi;
    
            // {} 실행코드 뒤에 ';'을 붙어야함
            mi = () -> {
                System.out.println("덧셈 함수입니다.");
            };
            mi.sum();
    
            // 실행코드가 한 줄일 경우 {} 생략 가능
            mi = () -> System.out.println("덧셈 함수입니다.");
            mi.sum();
        }
    }

    매개 변수와 리턴 값이 없을 경우 "() -> {}"의 형태로 람다식을 기술하면 된다. 만약, 중괄호 안에 실행문이 하나일 경우 중괄호를 제거할 수 있다. 위와 같이 인터페이스를 정의한 후, 객체가 가지고 있는 메서드를 호출하면 된다.

     

    덧셈 함수입니다.
    덧셈 함수입니다.

    실행 결과는 위와 같다.

     

    2. 매개 변수가 있고, 리턴 값이 없는 람다식
    @FunctionalInterface
    public interface MyFunctionInterface {
        public void sum(int x, int y);
    }

    MyfunctionalInterface에서 sum() 메서드에 매개 변수 int x, int y를 추가한다.

     

    
    public class Main {
        public static void main(String[] args) {
            // 객체 선언
            MyFunctionalInterface mi;
    
            // {} 실행코드 뒤에 ';'을 붙여야함
            mi = (x, y) -> {
                System.out.println(x + " + " + y + " = " + (x + y));
            };
            mi.sum(3, 6);
    
            // 실행코드가 한 줄일 경우 {} 생략 가능
            mi = (x, y) -> System.out.println(x + " + " + y + " = " + (x + y));
            mi.sum(2, 7);
        }
    }

    인터페이스 객체를 정의해 주고, 객체가 가지고 있는 메서드를 호출하면 된다.

     

    3 + 6 = 9
    2 + 7 = 9

    실행 결과는 위와 같다.

     

    3. 매개 변수가 없고, 리턴 값이 있는 람다식
    @FunctionalInterface
    public interface MyFunctionInterface {
        public String sum();
    }

    MyfunctionalInterface에서 sum() 메서드에 매개 변수를 없애고, 리턴 타입을 String으로 바꿔준다.

     

    public class Main {
        public static void main(String[] args) {
            // 객체 선언
            MyFunctionalInterface mi;
    
            // {} 실행코드 뒤에 ';'을 붙여야함
            mi = () -> {
                return "덧셈 함수입니다.";
            };
            System.out.println(mi.sum());
    
            // 실행코드가 return만 있는 경우 '{}'와 return문 생략 가능
            mi = () -> "덧셈 함수입니다.";
            System.out.println(mi.sum());
        }
    }

    위와 같이 인터페이스 객체를 정의하고 객체가 가지고 있는 메서드를 호출하면 된다. 중괄호 블록 안에 실행문이 return 뿐일 경우 위와 같이 중괄호와 return 문을 동시에 생략이 가능하다.

     

    덧셈 함수입니다.
    덧셈 함수입니다.

    실행 결과는 위와 같다.

     

    4. 매개 변수가 있고, 리턴 값이 있는 람다식
    @FunctionalInterface
    public interface MyFunctionInterface {
        public int sum(int x, int y);
    }

    MyFunctionalInterface에서 sum() 메서드에 리턴 타입을 int로 정의한다.

     

    public class Main {
        public static void main(String[] args) {
            // 객체 선언
            MyFunctionalInterface mi;
    
            // {} 실행코드 뒤에 ';'을 붙여야함
            mi = (x, y) -> {
                return x + y;
            };
            System.out.println(mi.sum(3, 6));
    
            // 실행코드가 return만 있는 경우 '{}'와 return문 생략 가능
            mi = (x, y) -> x + y;
            System.out.println(mi.sum(2, 7));
        }
    }

    위와 같이 인터페이스 객체를 정의하고 객체가 가지고 있는 메서드를 호출하면 된다. 중괄호 블록 안에 실행문이 return 뿐일 경우 위와 같이 중괄호와 return 문을 동시에 생략이 가능하다.

     

    9
    9

    실행 결과는 위와 같다.


    출처

    https://steady-coding.tistory.com/304

    ㆍ https://makecodework.tistory.com/entry/Java-%EB%9E%8C%EB%8B%A4%EC%8B%9DLambda-%EC%9D%B5%ED%9E%88%EA%B8%B0

     

    728x90

    'Language > Java' 카테고리의 다른 글

    Java - 스트림(Stream)의 기본 개념과 특징  (0) 2022.11.30
    Java - 표준 API의 함수적 인터페이스  (0) 2022.11.30
    Java - 열거 타입(enum)  (0) 2022.11.29
    Java - Custom Exception  (0) 2022.09.29
    Java - 예외 처리  (0) 2022.09.29

    댓글

Designed by Tistory.