람다식(Lambda Expression)

▶ 함수(메서드)를 간단한 '식(expression)'으로 표현하는 방법

 

[함수(메서드)]

int max(int a, int b){
    return a > b? a : b;
}

 

[람다식]

(a, b) -> a > b? a : b

 

익명 함수(이름이 없는 함수, anonymous function): 반환타입X, 함수 이름X

 

함수와 메서드의 차이

  • 근본적으로 동일. 함수는 일반적 용어, 메서드는 객체지향개념 용어
  • 함수는 클래스에 독립적, 메서드는 클래스에 종속적

 


람다식 작성하기

1. 메서드의 이름과 반환타입을 제거하고 '->' 를 블록{} 앞에 추가한다.

int max(int a, int b){
    return a > b? a : b;
}

(int a, int b) -> {
    return a > b? a : b;
}

 

 

2. 반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능(끝에 ' ; ' 안 붙임)

(int a, int b) -> {
    return a > b? a : b;
}

(int a, int b) -> a > b? a : b

 

 

3. 매개변수의 타입이 추론 가능하면 생략 가능(대부분의 경우 생략 가능)

(int a, int b) -> a > b? a : b

(a, b) -> a > b? a : b

 

 


람다식 작성하기 - 주의사항

1. 매개변수가 하나인 경우, 괄호() 생략 가능(타입이 없을 때만)

(a) -> a * a
(int a) -> a * a

a -> a * a //OK
int a -> a * a //에러

 

 

2. 블록 안의 문장이 하나뿐일 때, 괄호{} 생략 가능(끝에 ' ; ' 안 붙임)

(int i) -> {
    System.out.println(i);
}

(int i) -> System.out.println(i)

 

 


람다식의 예

//메서드
int max(int a, int b){
    return a > b? a : b;
}
//람다식
(a, b) -> a > b? a : b
//메서드
int printVar(String name, int i){
    System.out.println(name+"="+i);
}
//람다식
(name, i) -> System.out.println(name+"="+i)
//메서드
int square(int x){
    return x * x;
}
//람다식
x -> x * x
//메서드
int roll(){
    return (int) (Math.random()*6);
}
//람다식
() -> (int) (Math.random()*6)

 

 


람다식은 익명 객체

▶ 람다식은 익명 함수가 아니라 익명 객체이다.

(a, b) -> a > b? a : b
//========같은 것===========

new Object(){ //객체와 선언과 생성을 동시에
    int max(int a, int b){
        return a > b? a : b;
    }
};

 

람다식(익명 객체)을 다루기 위한 참조변수가 필요하다. 참조변수의 타입은?

Object obj = new Object(){
    int max(int a, int b){
        return a > b? a : b;
    }
};
타입 obj = (a, b) -> a > b? a : b; //어떤 타입?
int value = obj.max(3, 5) //에러. Object클래스에 max()가 없음

 

 


함수형 인터페이스

▶ 함수형 인터페이스 - 단 하나의 추상 메서드만 선언된 인터페이스

@FunctionalInterface
interface MyFunction {
	public abstract int max(int a, int b);
}

MyFunction f = new MyFunction(){
    public int max(int a, int b){
        return a > b? a : b;
    }
};
int value = f.max(3, 5) //OK. MyFunction에 max()가 있음

 

 

함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음

    (단, 함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환타입이 일치해야 함)

MyFunction f = (a, b) -> a > b? a : b;
int value = f.max(3, 5); //실제로는 람다식(익명 함수)이 호출됨

 

 

[예제: 람다식X]

package lambda;

public class Ex14_0 {
    public static void main(String[] args) {
        //Object obj = (a, b) -> a > b? a : b //람다식. 익명 객체
        MyFunction2 f = new MyFunction2(){
            public int max(int a, int b){ //오버라이딩 - 접근제어자는 좁게 못 바꾼다.
                return a > b? a : b;
            }
        };
        int value = f.max(3,5); //함수형 인터페이스 필요
        System.out.println("value=" + value);

    }
}
@FunctionalInterface //함수형 인터페이스는 단 하나의 추상메서드만 가져야 함
interface MyFunction2{
    int max(int a, int b);
}

실행 결과

 

[람다식]

package lambda;

public class Ex14_0 {
        //람다식(익명 객체)을 다루기 위한 참조변수의 타입은 함수형 인터페이스로 한다.
        MyFunction2 f = (a, b) -> a > b ? a : b; //람다식. 익명 객체

        int value = f.max(3,5); //람다식 호출
        System.out.println("value=" + value);

    }
}
@FunctionalInterface //함수형 인터페이스는 단 하나의 추상메서드만 가져야 함
interface MyFunction2{
    int max(int a, int b);
}

실행 결과

 

+ Recent posts