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