JAVA

람다식(Lamda Expression)

hohahihi 2023. 3. 15. 12:00

함수형 프로그래밍(functional programming)

  • 데이터를 어떻게 처리할지에 대한 함수를 정의하고 이를 데이터 처리부로 보내 데이터를 처리하는 기법
  • 함수를 전달 개체로 본다.
  • 동일 데이터에 대해서 어떤 함수를 사용하냐에 따라 결과가 달라진다.(데이터 처리의 다형성)
  • 메소드 : 클래스 또는 객체 안에서 객체의 기능을 정의한 것

람다식

  • 자바에서 함수형 프로그래밍을 위해 추가
  • Java 8부터 지원
  • 따로 이름을 정의하지 않고 사용.

 

람다식: (매개변수, ...) -> { 처리 내용 }

 

 

  • 자바는 객체지향 언어이기 때문에 람다식을 익명 구형 객체로 처리한다.

 

//익명 구현 객체
public void action(Calculable calculable) {
    int x = 10;
    int y = 4;
    calculable.calculate(x,y);    //데이터를 제공하고 추상 메소드를 
}

 

//람다식
action( (x,y) -> {
    int result = x + y;
    System.out.println(result);    
});

 


함수형 인터페이스(functional interface)

  • 추상 메소드가 하나만 정의되어 있는 인터페이스
  • 인터페이스의 익명 구현 객체를 람다식으로 표현하려면 인터페이스가 단 하나의 추상 메소드만 가져야 한다.(= 함수형 인터페이스만 람다식으로 표현 가능)
  • @FunctionalInterface 어노테이션 사용(생략 가능)
    - 컴파일 과정에서 추상 메소드가 하나만 있는지 검사 

 

//함수형 인터페이스
@FunctionalInterface
public interface Calculable {
    //추상 메소드
    void calculate(int x, int y);
 
}
 

 

public class LamdaExample {
    public static void main(String[] args) {
        
        //더하기
        action((x,y) -> {
            int result = x + y;
            System.out.println("result : " + result);
        });
        
        //뺴기
        action((x,y) -> {
            int result = x - y;
            System.out.println("result : " + result);
        });
    }
 
    public static void action(Calculable calculable) {
        
        //데이터
        int x = 10;
        int y = 4;
        
        //데이터 처리
        calculable.calculate(x, y);
    }
}

 

 


매개변수가 없는 람다식

  • 함수형 인터페이스의 추상 메소드에 매개변수가 없는 경우
  • 안드로이드 개발 시 UI에 대한 처리할 때 자주 사용

 

() -> {
    실행문1;
    실행문2;
}

 


매개변수가 있는 람다식

  • 데이터 타입 생략 가능
  • 매개변수의 순서와 개수가 중요

 

(데이터타입 매개변수, ...) -> {
    실행문1;
    실행문2;
}

 

(var 매개변수, ...) -> {
    실행문1;
    실행문2;
}

 

(매개변수, ...) -> {
    실행문1;
    실행문2;
}

 


리턴 값이 있는 람다식

  • 함수형 인터페이스의 추상 메소드에 리턴 값이 있으면 람다식 내부에 return 문을 작성해야 한다.
  • return 문 한 줄만 있는 경우에는 return 키워드를 생략하고 연산식이나 메소드 호출하는 문장으로 대체할 수 있다.

 

//실행문이 여러 개일 경우
(매개변수, ...) -> {
    실행문1;
    실행문2;
    return 값;
}

 

//return 문만 작성하는 경우
(매개변수, ...) -> 값;

 


메소드 참조

  • 메소드를 참조해서 매개변수의 정보 및 리턴 타입을 알아내 람다식에서 불필요한 매개변수를 제거하는 것을 목적으로 한다.
  • 람다식에 비해 코드는 간략해지지만 가독성은 람다식보다 떨어진다.
    - 가독성을 위해 일부러 람다식을 사용하기도 한다.

 


정적 메소드와 인스턴스 메소드 참조

  • 인스턴스 메소드는 객체 참조 변수를 먼저 선언한 다음 참조 변수로 메소드 참조가 가능하다.

 

정적 메소드 참조

//람다식
(a, b) -> { return 클래스.staticMethod(a, b); }
(a, b) -> 클래스.staticMethod(a, b)
 
//정적 메소드 참조
클래스 :: staticMetchod

 

인스턴스 메소드 참조

//람다식
(a, b) -> { return 참조변수.instanceMetchod(a, b); }
(a, b) -> 참조변수.instanceMetchod(a, b)
 
//인스턴스 메소드 참조
참조변수:: instanceMetchod

 


매개변수의 메소드 참조

  • 형식은 정적 메소드 참조와 동일하다.

 

//람다식
(a, b) -> { a.instatnceMetho(b); }
 
//매개변수의 메소드 참조
클래스 :: instanceMethod

 


생성자 참조

  • 람다식이 단순히 객체를 생성하고 리턴하도록 구성되어 있는 경우
  • 매개변수의 개수는 인터페이스의 추상 메소드에 정의된 매개변수에 의해 결정된다.

 

//람다식
(a, b) -> { return new 클래스(a, b); }
(a, b) -> new 클래스(a, b)
 
//생성자 참조
클래스 :: new

 

  • 인터페이스의 추상 메소드가 어떻게 선언되어 있는지 확인해야 올바른 람다식 작성 및 메소드,생성자 참조가 가능하다.