Lambda

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ λ³‘λ ¬μ²˜λ¦¬μ™€ 이벀트 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ— μ ν•©ν•˜κΈ° λ•Œλ¬Έμ— λΆ€κ°λ˜κ³ μžˆλ‹€. μžλ°”λŠ” ν•¨μˆ˜μ  ν”„λ‘œκ·Έλž˜λ°μ„ μœ„ν•΄ λžŒλ‹€μ‹μ„ λ„μž…ν–ˆλ‹€.

λžŒλ‹€μ‹μ€ 읡λͺ… ν•¨μˆ˜λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ μ‹μœΌλ‘œ 객체 지ν–₯ μ–Έμ–΄λ³΄λ‹€λŠ” ν•¨μˆ˜ 지ν–₯ 언어에 가깝닀.

  1. μžλ°” μ½”λ“œκ°€ 맀우 κ°„κ²° 해짐

  2. μ»¬λ ‰μ…˜μ˜ μš”μ†Œλ₯Ό ν•„ν„°λ§ν•˜κ±°λ‚˜ 맀핑해 μ›ν•˜λŠ” κ²°κ³Όλ₯Ό μ‰½κ²Œ 집계할 수 있음

λžŒλ‹€λž€?

LambdaλŠ” λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜μ˜ μ‹μœΌλ‘œ ν‘œν˜„ν•œ κ²ƒμœΌλ‘œ, 읡λͺ…λ©”μ„œλ“œ 생성 문법이라 λ³Ό 수 μžˆλ‹€. 즉, λ©”μ„œλ“œλͺ…없이 κ΅¬ν˜„λΆ€λ§ŒμœΌλ‘œ μ„ μ–Έν•œ 것이닀. ν•˜μ§€λ§Œ Java의 λ©”μ„œλ“œλŠ” λ©”μ„œλ“œ 자체둜 혼자 μ„ μ–Έν•˜μ—¬ 쓰일 수 μ—†μœΌλ©°, 무쑰건 Class κ΅¬μ„±λ©€λ²„λ‘œ μ„ μ–Έλ˜μ–΄μ•Όν•œλ‹€. Lambdaλ₯Ό ν†΅ν•΄μ„œ μƒμ„±λ˜λŠ” 것은 λ©”μ„œλ“œ μžμ²΄κ°€ μ•„λ‹Œ μ‹€ν–‰λ¬Έ(λ©”μ„œλ“œ)λ₯Ό 가진 객체이닀. λžŒλ‹€μ‹μ€ 일반적인 객체가 μ•„λ‹Œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 읡λͺ…κ΅¬ν˜„κ°μ²΄λ₯Ό μƒμ„±ν•œλ‹€.

λžŒλ‹€μ‹ -> λ§€κ°œλ³€μˆ˜λ₯Ό 가진 μ½”λ“œ 블둝 -> 읡λͺ…κ΅¬ν˜„κ°μ²΄

λžŒλ‹€μ‹μ˜ ν˜•νƒœλŠ” 맀개 λ³€μˆ˜λ₯Ό 가진 μ½”λ“œ λΈ”λ‘μ΄μ§€λ§Œ, λŸ°νƒ€μž„ μ‹œμ— 읡λͺ… κ΅¬ν˜„ 객체λ₯Ό 생성

Runnable runnable = new Runnable(){ //읡λͺ…κ΅¬ν˜„κ°μ²΄
    public void run(){...}
};
Runnable runnable = () -> {...}; //λžŒλ‹€μ‹

λžŒλ‹€μ‹μ€ (λ§€κ°œλ³€μˆ˜)->{μ‹€ν–‰μ½”λ“œ} 의 ν˜•νƒœλ‘œ μž‘μ„±λœλ‹€.

λžŒλ‹€μ‹ κΈ°λ³Έ 문법

(νƒ€μž… λ§€κ°œλ³€μˆ˜, ...)->{μ‹€ν–‰λ¬Έ; ...}
  • (νƒ€μž… λ§€κ°œλ³€μˆ˜, ...) : 였λ₯Έμͺ½ μ€‘κ΄„ν˜Έ {}λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ 값을 μ œκ³΅ν•˜λŠ” μ—­ν• , λ§€κ°œλ³€μˆ˜ 이름은 κ°œλ°œμžκ°€ 자유둭게 쀄 수 μžˆλ‹€.

  • -> : 맀개 λ³€μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ€‘κ΄„ν˜Έ{} λ₯Ό μ‹€ν–‰

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

맀개 λ³€μˆ˜ νƒ€μž…μ€ λŸ°νƒ€μž„μ‹œμ— λŒ€μž…λ˜λŠ” 값에 따라 μžλ™μœΌλ‘œ 인식될 수 있기 λ•Œλ¬Έμ— λžŒλ‹€μ‹μ—μ„œλŠ” 맀개 λ³€μˆ˜μ˜ νƒ€μž…μ„ 일반적으둜 μ–ΈκΈ‰ν•˜μ§€ μ•ŠλŠ”λ‹€.

(a)->{System.out.println(a);}

ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜λ§Œ μžˆλ‹€λ©΄ () λ₯Ό μƒλž΅ν•  수 있고, ν•˜λ‚˜μ˜ μ‹€ν–‰λ¬Έλ§Œ μžˆλ‹€λ©΄ {} 도 μƒλž΅ν•  수 μžˆλ‹€.

a -> System.out.println(a);

λ§Œμ•½ λ§€κ°œλ³€μˆ˜κ°€ μ—†λ‹€λ©΄ λΉˆκ΄„ν˜Έ() λ₯Ό λ°˜λ“œμ‹œ μ‚¬μš©ν•΄μ•Όν•œλ‹€.

(x,y) -> { return x+y; }

싀행문을 μ‹€ν–‰ν•˜κ³  결과값을 λ¦¬ν„΄ν•΄μ•Όν•œλ‹€λ©΄ μœ„μ™€ 같이 return문으둜 결과값을 지정할 수 μžˆλ‹€.

(x,y) -> x+y

λ§Œμ•½ {} 에 return문만 μžˆλŠ” κ²½μš°μ—λŠ” μœ„μ™€ 같이 return문을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  μž‘μ„±ν•  수 μžˆλ‹€.

νƒ€κ²Ÿ νƒ€μž…κ³Ό ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€

μΈν„°νŽ˜μ΄μŠ€ λ³€μˆ˜ = λžŒλ‹€μ‹;

λžŒλ‹€μ‹μ€ μΈν„°νŽ˜μ΄μŠ€ λ³€μˆ˜μ— λŒ€μž…λœλ‹€. 즉, λžŒλ‹€μ‹μ€ μΈν„°νŽ˜μ΄μŠ€μ˜ 읡λͺ… κ΅¬ν˜„ 객체λ₯Ό μƒμ„±ν•œλ‹€λŠ” λœ»μ΄λ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” 직접 객체화할 수 μ—†κΈ° λ•Œλ¬Έμ— 읡λͺ… κ΅¬ν˜„ 클래슀λ₯Ό μƒμ„±ν•˜κ³  κ°μ²΄ν™”ν•œλ‹€. λžŒλ‹€μ‹μ€ λŒ€μž…λ  μΈν„°νŽ˜μ΄μŠ€μ˜ μ’…λ₯˜μ— 따라 μž‘μ„±λ²•μ΄ 달라지기 λ•Œλ¬Έμ— λžŒλ‹€μ‹μ΄ λŒ€μž…λ  μΈν„°νŽ˜μ΄μŠ€λ₯Ό λžŒλ‹€μ‹μ˜ νƒ€κ²Ÿνƒ€μž…(target type)이라 ν•œλ‹€.

@FunctionallInterface ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€

λžŒλ‹€μ‹μ΄ ν•˜λ‚˜μ˜ λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•˜κΈ° λ•Œλ¬Έμ— 두 개 μ΄μƒμ˜ 좔상 λ©”μ†Œλ“œκ°€ μ„ μ–Έλœ μΈν„°νŽ˜μ΄μŠ€λŠ” λžŒλ‹€μ‹μ„ μ΄μš©ν•΄μ„œ κ΅¬ν˜„κ°μ²΄λ₯Ό 생성할 수 μ—†λ‹€. 즉, ν•˜λ‚˜μ˜ 좔상 λ©”μ†Œλ“œκ°€ μ„ μ–Έλœ μΈν„°νŽ˜μ΄μŠ€λ§Œμ΄ λžŒλ‹€μ‹μ˜ νƒ€κ²Ÿ νƒ€μž…μ΄ 될 수 있으며, 이λ₯Ό ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€λΌ ν•œλ‹€. μΈν„°νŽ˜μ΄μŠ€ μ„ μ–Έμ‹œ @FunctionallInterface μ–΄λ…Έν…Œμ΄μ…˜μ„ 뢙이면 μ»΄νŒŒμΌλŸ¬κ°€ 두 개 μ΄μƒμ˜ 좔상 λ©”μ†Œλ“œκ°€ μ„ μ–Έλ˜μ§€ μ•Šλ„λ‘ 체킹해쀀닀.

@FunctionalInterface
public interface MyFunctionalInterface{
    public void methodA();
    public void methodB(); // 컴파일 였λ₯˜
}

맀개 λ³€μˆ˜μ™€ 리턴값이 μ—†λŠ” λžŒλ‹€μ‹

@FunctionalInterface
public interface MyFunctionalInterface{
    public void method();
}
MyFunctionalInterface fi = ()->{...}

method()κ°€ λ§€κ°œλ³€μˆ˜ 값을 가지지 μ•ŠκΈ° λ•Œλ¬Έμ— λžŒλ‹€μ‹μ—μ„œ λ§€κ°œλ³€μˆ˜κ°€ μ—†λ‹€.

fi.method();

λžŒλ‹€μ‹μ΄ λŒ€μž…λœ μΈν„°νŽ˜μ΄μŠ€μ˜ μ°Έμ‘° λ³€μˆ˜λŠ” μœ„μ™€ 같이 method()λ₯Ό ν˜ΈμΆœν•  수 있으며, ν˜ΈμΆœμ€ λžŒλ‹€μ‹μ˜ {...} λ₯Ό μ‹€ν–‰μ‹œν‚¨λ‹€.

맀개 λ³€μˆ˜κ°€ μžˆλŠ” λžŒλ‹€μ‹

@FunctionalInterface
public interface MyFunctionalInterface{
    public void method(int x);
}
MyFunctionalInterface fi = (x)->{...}
MyFunctionalInterface fi = x -> {...}
fi.method(5);

리턴값이 μžˆλŠ” λžŒλ‹€μ‹

@FunctionalInterface
public interface MyFunctionalInterface{
    public int method(int x, int y);
}
MyFunctionalInterface fi = (x, y)->{ ... ; return κ°’; }
MyFunctionalInterface fi = (x, y)->{ 
    return x + y;
}
MyFunctionalInterface fi = (x, y) -> x + y;
int result = fi.method(2,5);

클래슀 멀버와 둜컬 λ³€μˆ˜ μ‚¬μš©

λžŒλ‹€μ‹μ˜ μ‹€ν–‰ λΈ”λ‘μ—λŠ” 클래슀의 멀버(ν•„λ“œ, λ©”μ†Œλ“œ) 및 둜컬 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

클래슀 멀버 μ‚¬μš©

클래슀의 멀버인 ν•„λ“œμ™€ λ©”μ†Œλ“œλŠ” μ œμ•½μ—†μ΄ μ‚¬μš©ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” μ£Όμ˜κ°€ ν•„μš”ν•˜λ‹€.

일반적으둜 읡λͺ… 객체 λ‚΄λΆ€μ—μ„œ thisλŠ” 읡λͺ… 객체의 μ°Έμ‘°μ΄μ§€λ§Œ, λžŒλ‹€μ‹μ—μ„œ thisλŠ” λ‚΄λΆ€μ μœΌλ‘œ μƒμ„±λ˜λŠ” λžŒλ‹€μ‹μ„ μ‹€ν–‰ν•œ 객체의 참쑰이닀.

public interface MyFunctionalInterface{
    public void method();
}
public class UsingThis{
    public int outterField = 10;

    class Inner{
        int innerField = 20;

        void method(){
            //λžŒλ‹€μ‹
            MyFunctionalInterface fi = ()->{
                // λ°”κΉ₯ 객체의 μ°Έμ‘°λ₯Ό μ–»κΈ° μœ„ν•΄μ„œλŠ” 클래슀λͺ….thisμ‚¬μš©
                System.out.println("outterField : "+ UsingThis.this.outterField);
                // λžŒλ‹€μ‹ λ‚΄λΆ€μ—μ„œ thisλŠ” Inner 객체λ₯Ό 잠쑰
                System.out.println("innerField : "+ this.innerField);
            };
            fi.method();
        }
    }
}
public class UsingThisEx {
    public static void main(String... args){
        UsingThis usingThis = new UsingThis();
        UsignThis.Inner inner = usingThis.new Inner();
        inner.method();
    }
}

둜컬 λ³€μˆ˜ μ‚¬μš©

λžŒλ‹€μ‹μ€ λ©”μ†Œλ“œ λ‚΄λΆ€μ—μ„œ 주둜 μž‘μ„±λ˜λ―€λ‘œ 둜컬 읡λͺ… κ΅¬ν˜„ 객체λ₯Ό μƒμ„±μ‹œν‚¨λ‹€κ³  λ΄μ•Όν•œλ‹€. λžŒλ‹€μ‹μ—μ„œ λ°”κΉ₯ 클래슀의 ν•„λ“œλ‚˜ λ©”μ†Œλ“œλŠ” μ œν•œ 없이 μ‚¬μš©ν•  수 μžˆμœΌλ‚˜, λ©”μ†Œλ“œμ˜ λ§€κ°œλ³€μˆ˜ λ˜λŠ” 둜컬 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ 이 두 λ³€μˆ˜λŠ” final νŠΉμ„±μ„ κ°€μ Έμ•Όν•œλ‹€.

[09. 쀑첩 ν΄λž˜μŠ€μ™€ 쀑첩 μΈν„°νŽ˜μ΄μŠ€ - 읡λͺ…κ°μ²΄μ˜ 둜컬 λ³€μˆ˜ μ‚¬μš© λ₯Ό μ°Έμ‘°]

맀개 λ³€μˆ˜ λ˜λŠ” 둜컬 λ³€μˆ˜λ₯Ό λžŒλ‹€μ‹μ—μ„œ μ½λŠ” 것은 ν—ˆμš©λ˜μ§€λ§Œ, λžŒλ‹€μ‹ λ‚΄λΆ€ λ˜λŠ” μ™ΈλΆ€μ—μ„œ λ³€κ²½ν•  수 μ—†λ‹€.

public interface MyFunctionalInterface{
    public void method();
}
public class UsingLocalVariable{
    // argλŠ” final νŠΉμ„±
    void method(int arg){
        int localVar = 40; // localVal final νŠΉμ„±

        // finalνŠΉμ„±λ•Œλ¬Έμ— λ³€κ²½ λΆˆκ°€
        // arg = 31;
        // localVal = 20;

        // λžŒλ‹€μ‹
        MyFunctionalInterface fi = () -> {
            System.out.println("arg: " + arg);
            System.out.println("localVal: " + localVal);
        };
        fi.method();
    }
}

Last updated

Was this helpful?