Lambda Expression

chamingยท2021๋…„ 12์›” 12์ผ
0

JAVA

๋ชฉ๋ก ๋ณด๊ธฐ
4/4

Epilogue๐Ÿ™Žโ€โ™€๏ธ
๋‚˜์ค‘์— ๊ณต๋ถ€ํ•ด์•ผ์ง€ ํ•˜๊ณ  ๋ฏธ๋ฃจ๊ณ  ๊ทธ๋ƒฅ ๊ตฌ๊ธ€๋ง๋งŒํ•ด์„œ ๊ทธ ๋•Œ ๊ทธ ๋•Œ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ,๋Šฆ์—ˆ์ง€๋งŒ ์ง€๊ธˆ์ด๋ผ๋„ ์ œ๋Œ€๋กœ ์•Œ๊ณ  ์‚ฌ์šฉํ•˜์ž ์ƒ๊ฐ์ด ๋“ค์–ด ์ •๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•ด๋ด…๋‹ˆ๋‹ค!!

๋žŒ๋‹ค์‹์€ ์ต๋ช…ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์‹์œผ๋กœ ๊ฐ์ฒด์ง€ํ–ฅ์–ธ์–ด๋ณด๋‹ค๋Š” ํ•จ์ˆ˜์ง€ํ–ฅ์–ธ์–ด์— ๊ฐ€๊น๋‹ค. (java8๋ถ€ํ„ฐ ์ง€์›)

์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ , ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๋งคํ•‘ํ•˜์—ฌ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ 

๋žŒ๋‹ค์‹์˜ ํ˜•ํƒœ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง„ ์ฝ”๋“œ ๋ธ”๋ก์ด์ง€๋งŒ, ๋Ÿฐํƒ€์ž„ ์‹œ์—๋Š” ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

  • ๋žŒ๋‹ค์‹ -> ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง„ ์ฝ”๋“œ ๋ธ”๋ก -> ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด
Runnable runnable = new Runnable() {	// ์ต๋ช… ๊ตฌํ˜„ ๊ฐ์ฒด
  public void method();  
};

// ๋žŒ๋‹ค์‹ ํ‘œํ˜„
Runnable runnable = (ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜, ...) -> {์‹คํ–‰๋ฌธ; ...};

ํƒ€๊ฒŸํƒ€์ž…๊ณผ ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค

ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค(@FunctionalInteface)

๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋žŒ๋‹ค์‹์˜ ํƒ€์ผ“ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , ๋žŒ๋‹ค์‹์ด ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋žŒ๋‹ค์‹์„ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค.

ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์ด ๋žŒ๋‹ค์‹์˜ ํƒ€๊ฒŸํƒ€์ž…์ด ๋  ์ˆ˜ ์žˆ๋‹ค. = ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค

์ด๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด @FunctionalInterface์ด๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฆฌํ„ด๊ฐ’๋ณ„ ๋žŒ๋‹ค์‹ํ‘œํ˜„

๋žŒ๋‹ค์‹ ํ‘œํ˜„์„ ์œ„ํ•œ MyFunctionalInterface Class

@FunctionalInterface
public Interface MyFunctionalInterface{
    // (โ€ป์ฃผ์˜) ๋ฉ”์†Œ๋“œ๋Š” ๋ฌด์กฐ๊ฑด ํ•˜๋‚˜๋งŒ ์„ ์–ธ์ด ๊ฐ€๋Šฅํ•˜๋‚˜, ์„ค๋ช…์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์„ ์–ธํ•œ ๊ฒƒ์ž„
    public void method();				// 1.๋งค๊ฐœ๋ณ€์ˆ˜X , ๋ฆฌํ„ด๊ฐ’X
    public void method(int a);			// 2.๋งค๊ฐœ๋ณ€์ˆ˜O , ๋ฆฌํ„ด๊ฐ’X
    public int method(int a, int b);	// 3.๋งค๊ฐœ๋ณ€์ˆ˜O , ๋ฆฌํ„ด๊ฐ’O
}

์‹คํ–‰๋ฌธ

public class MyFunctionalInterfaceExample{
    public static void main(String[] args){
        // 1.๋งค๊ฐœ๋ณ€์ˆ˜X , ๋ฆฌํ„ด๊ฐ’X
        MyFunctionalInterface fi = () -> System.out.println("test");
        fi.method();		// test
        
        // 2.๋งค๊ฐœ๋ณ€์ˆ˜O , ๋ฆฌํ„ด๊ฐ’X
        MyFunctionalInterface fi2 = (a) -> System.out.println(a+2);
        fi2.method(5);		// 7
        
        // 3.๋งค๊ฐœ๋ณ€์ˆ˜O , ๋ฆฌํ„ด๊ฐ’O
        MyFunctionalInterface fi3 = (a, b) -> {return a+b};
        fi2.method(fi3.method(5,7));		// 12
    }
}

ํด๋ž˜์Šค ๋ฉค๋ฒ„์™€ ๋กœ์ปฌ ๋ณ€์ˆ˜ ์‚ฌ์šฉ

๋žŒ๋‹ค์‹์˜ ์‹คํ–‰ ๋ธ”๋ก์—๋Š” ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ฐ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„๋Š” ์ œ์•ฝ ์‚ฌํ•ญ ์—†์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” ์ œ์•ฝ์‚ฌํ•ญ์ด ๋”ฐ๋ฅธ๋‹ค.

โ—this ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ์‹œ ์ฃผ์˜ ํ•„์š”

  • ์ผ๋ฐ˜์ ์ธ ์ต๋ช… ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ์˜ this๋Š” ์ต๋ช… ๊ฐ์ฒด์˜ ์ฐธ์กฐ
  • ๋žŒ๋‹ค์‹์—์„œ์˜ this๋Š” ๋žŒ๋‹ค์‹์„ ์‹คํ–‰ํ•œ ๊ฐ์ฒด์˜ ์ฐธ์กฐ์ด๋‹ค.
public class UsingThis {
    public int outterField = 10;

    class Inner{
        int innerField = 20;
        void method(){
            MyFunctionalInterface fi = () -> {
                
                System.out.println("outterField :: " + outterField);
                // ๋ฐ”๊นฅ๊ฐ์ฒด์˜ ์ฐธ๊ณ ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ํด๋ž˜์Šค๋ช….this
                System.out.println("outterField :: " + UsingThis.this.outterField);

                System.out.println("innerField :: " + innerField);
                // ๋žŒ๋‹ค์‹ ๋‚ด๋ถ€์—์„œ์˜ this๋Š” ์ค‘์ฒฉ๊ฐ์ฒด์ธ Inner๋ฅผ ์ฐธ์กฐ
                System.out.println("innerField :: " + this.innerField);
            };
            fi.method();
        }
    }

    public static void main(String... args){
        UsingThis usingThis = new UsingThis();
        UsingThis.Inner inner = usingThis.new Inner();
        inner.method();
    }
}

โ—๋กœ์ปฌ ๋ณ€์ˆ˜ ์‚ฌ์šฉ

  • ๋žŒ๋‹ค์‹์—์„œ ๋ฐ”๊นฅ ํด๋ž˜์Šค์˜ ํ•„๋“œ๋‚˜ ๋ฉ”์†Œ๋“œ๋Š” ์ œํ•œ ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ๋กœ์ปฌ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋‘ ๋ณ€์ˆ˜๋Š” finalํŠน์„ฑ์„ ๊ฐ€์ ธ์•ผํ•œ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ๋กœ์ปฌ๋ณ€์ˆ˜๋ฅผ ์ฝ๋Š”๊ฒƒ์€ ํ—ˆ์šฉํ•˜์ง€๋งŒ, ๋žŒ๋‹ค์‹์˜ ๋‚ด๋ถ€ ๋˜๋Š” ์™ธ๋ถ€์—์„œ ๋ณ€๊ฒฝ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
public class UsingLocalVariable {
    void method(int arg){   // arg๋Š” finalํŠน์„ฑ์„ ๊ฐ€์ง
        int localVar = 40;  // localVar๋Š” final์˜ ํŠน์„ฑ์„ ๊ฐ€์ง

//        arg = 31;         // final ํŠน์„ฑ๋•Œ๋ฌธ์— ์ˆ˜์ • ๋ถˆ๊ฐ€, ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
//        localVar = 30;    // final ํŠน์„ฑ๋•Œ๋ฌธ์— ์ˆ˜์ • ๋ถˆ๊ฐ€, ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

        // lambda
        MyFunctionalInterface fi = () -> {
            System.out.println("arg : " + arg);
            System.out.println("localVar : " + localVar);
        };
        fi.method();
    }

    public static void main(String... args){
        UsingLocalVariable usingLocalVariable = new UsingLocalVariable();
        usingLocalVariable.method(50);
        // 50
        // 40
    }
}

ํ‘œ์ค€ API์˜ ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค

์ข…๋ฅ˜์ถ”์ƒ๋ฉ”์†Œ๋“œ ํŠน์ง•๋ฉ”์†Œ๋“œ
Consumer๋งค๊ฐœ๊ฐ’O , ๋ฆฌํ„ด๊ฐ’Xaccept()
Supplier๋งค๊ฐœ๊ฐ’X, ๋ฆฌํ„ด๊ฐ’OgetXXX()
Function๋งค๊ฐœ๊ฐ’O, ๋ฆฌํ„ด๊ฐ’O
๋งค๊ฐœ๊ฐ’์„ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ๋งคํ•‘(ํƒ€์ž… ๋ณ€ํ™˜)
applyXXX()
Operator๋งค๊ฐœ๊ฐ’O, ๋ฆฌํ„ด๊ฐ’O
๋งค๊ฐœ๊ฐ’์„ ์—ฐ์‚ฐํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด
applyXXX()
Perdicate๋งค๊ฐœ๊ฐ’O, ๋ฆฌํ„ด๊ฐ’ booleantestXXX()

โœ…Consumer : ๋ฆฌํ„ด๊ฐ’์ด ์—†๋Š” accept() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง

public class ConsumerExample {
    public static void main(String[] args){
        // ๊ฐ์ฒด t๋ฅผ ๋ฐ›์•„ ์†Œ๋น„
        Consumer<String> consumer = t-> System.out.println("test "+t);
        consumer.accept("java");

        // ๊ฐ์ฒด x์™€ y๋ฅผ ๋ฐ›์•„ ์†Œ๋น„
        BiConsumer<String, String> biConsumer = (x,y) ->System.out.println(x+ "::"+ y);
        biConsumer.accept("hello", "java");

        // double๊ฐ’์„ ๋ฐ›์•„ ์†Œ๋น„
        DoubleConsumer doubleConsumer = t -> System.out.println("java" + t);
        doubleConsumer.accept(0.8);

        // ๊ฐ์ฒดa์™€ int b๊ฐ’์„ ๋ฐ›์•„ ์†Œ๋น„ accept(T t, int value)
        ObjIntConsumer<String> objIntConsumer = (a, b) -> System.out.println(a + b);
        objIntConsumer.accept("hello", 8);
    }
}

โœ…Supplier : ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๊ณ  ๋ฆฌํ„ด๊ฐ’์ด ์žˆ๋Š” getXXX() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง

ex) Supplier : T๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ด

โ€‹ BooleanSupplier : boolean getAsBoolean()

public class SupplierExample {
    public static void main(String[] args){
        // ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์—†๊ณ , int๊ฐ’์„ ๋ฆฌํ„ด
        IntSupplier intSupplier = () ->{
            int num = (int)(Math.random() * 6) +1;
            return num;
        };
        System.out.println("์ฃผ์‚ฌ์œ„ ๋ˆˆ์˜ ์ˆ˜ : "+intSupplier.getAsInt());
    }
}

โœ…Function: ๋งค๊ฐœ๊ฐ’์ด ์žˆ๊ณ  ๋ฆฌํ„ด๊ฐ’์ด ์žˆ๋Š” applyXXX() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง

(์ฐธ๊ณ ) Student Class : name(String) , englishScore(int), mathScore(int) ๋ณ€์ˆ˜ ๊ฐ€์ง

public class FunctionExample1 {
    private static List<Student> list = Arrays.asList(
            new Student("์ฐจ", 100,100),
            new Student("๊น€", 95 , 80)
    );

    // Function<T,R> : ๊ฐ์ฒดT๋ฅผ ๊ฐ์ฒดR๋กœ ๋งคํ•‘
    public static void printString(Function<Student, String> function){
        for(Student student : list){
            // ๋žŒ๋‹ค์‹ ์‹คํ–‰ : R apply(T)
            System.out.print(function.apply(student) + " ");
        }
        System.out.println();
    }
    
	// ToIntFunction<T t> : ๊ฐ์ฒด T๋ฅผ int๋กœ ๋งคํ•‘
    public static void printInt(ToIntFunction<Student> function){
        for(Student student : list){
            // ๋žŒ๋‹ค์‹ ์‹คํ–‰ : int applyeAsInt(T t)
            System.out.print(function.applyAsInt(student)+ " ");
        }
        System.out.println();
    }

    public static void main(String... args){
        System.out.println("ํ•™์ƒ ์ด๋ฆ„");
        printString(t -> t.getName());

        System.out.println("์˜์–ด ์ ์ˆ˜");
        printInt( t -> t.getEnglishScore());

        System.out.println("์ˆ˜ํ•™ ์ ์ˆ˜");
        printInt(t -> t.getMathScore());
    }
}

โœ…Operator : ๋งค๊ฐœ๊ฐ’์ด ์žˆ๊ณ  ๋ฆฌํ„ด๊ฐ’์ด ์žˆ๋Š” applyXXX() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง

Function๊ณผ์˜ ์ฐจ์ด์ ์€ ๋งค๊ฐœ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ์—ญํ• ๋ณด๋‹ค๋Š” ๋งค๊ฐœ๊ฐ’์„ ์ด์šฉํ•ด ์—ฐ์‚ฐ์ˆ˜ํ–‰ ํ›„ ๋™์ผํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

public class OperatorExample {
    private static int[] scores = {92, 85, 86};

    // IntBianryOperator : ๋‘ ๊ฐœ์˜ int ์—ฐ์‚ฐ
    public static int maxOrMin(IntBinaryOperator operator){
        int result = scores[0];
        for(int score: scores){
            // ๋žŒ๋‹ค์‹ ์‹คํ–‰ : int applyAsInt(int)
            result = operator.applyAsInt(result, score);
        }
        return result;
    }

    public static void main(String... args){
        int max = maxOrMin(
                (a,b) -> {
                    if(a >= b) return a;
                    else return b;
                }
        );
        System.out.println("์ตœ๋Œ€๊ฐ’ : "+max);

        int min = maxOrMin(
                (a,b) -> {
                    if(a <= b) return a;
                    else return b;
                }
        );
        System.out.println("์ตœ์†Ÿ๊ฐ’ : "+min);
    }
}

โœ…Predicate : ๋งค๊ฐœ๊ฐ’์ด ์žˆ๊ณ  boolean ๋ฆฌํ„ด๊ฐ’์ด ์žˆ๋Š” testXXX() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง

public class PredicateExample {
    private static List<Student> list = Arrays.asList(
            new Student("์ฐจ์ฐจ์ฐจ", "์—ฌ์ž", 90),
            new Student("Lee", "์—ฌ์ž", 77),
            new Student("๊น€๊น€๊น€","๋‚จ์ž", 80),
            new Student("์ •์ •์ •","๋‚จ์ž", 60)
    );
    
    // Predicate<T> : ๊ฐ์ฒด T๋ฅผ ์กฐ์‚ฌ
    public static double avg(Predicate<Student> predicate){
        int count = 0 ;
        int sum = 0;
        for(Student student : list){
            // boolean test(T t)
            if(predicate.test(student)){
                count++;
                sum += student.getMathScore();
            }
        }
        return (double) sum / count;
    }
    
    // ๋‚จ์ž, ์—ฌ์ž ํ‰๊ท  ์ ์ˆ˜ ๊ตฌํ•˜๊ธฐ
    public static void main(String... args){
        double maleAvg = avg(t-> t.getSex().equals("๋‚จ์ž"));
         System.out.println("๋‚จ์ž ํ‰๊ท  ์ ์ˆ˜ : "+maleAvg);

        double femaleAvg = avg(t-> t.getSex().equals("์—ฌ์ž"));
         System.out.println("์—ฌ์ž ํ‰๊ท  ์ ์ˆ˜ : "+femaleAvg);
     }
}

andThen()๊ณผ compose() ๋””ํดํŠธ ๋ฉ”์†Œ๋“œ

๋””ํดํŠธ ๋ฐ ์ •์ ๋ฉ”์†Œ๋“œ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค์— ์„ ์–ธ๋˜์–ด๋„ ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค์˜ ์„ฑ์งˆ์„ ์žƒ์ง€ ์•Š๋Š”๋‹ค. java.util.functionํŒจํ‚ค์ง€์˜ ํ•จ์ˆ˜์  ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ๋””ํดํŠธ ๋ฐ ์ •์ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.

์ธํ„ฐํŽ˜์ด์ŠคAB = ์ธํ„ฐํŽ˜์ด์ŠคA.andThen(์ธํ„ฐํŽ˜์ด์ŠคB);

์ตœ์ข…๊ฒฐ๊ณผ = ์ธํ„ฐํŽ˜์ด์ŠคAB.method();

โœ…andThen()

์ธํ„ฐํŽ˜์ด์ŠคAB์˜ method()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์šฐ์„  ์ธํ„ฐํŽ˜์ด์ŠคA๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ธํ„ฐํŽ˜์ด์ŠคB์˜ ๋งค๊ฐœ๊ฐ’์œผ๋กœ ์ œ๊ณต.

์ธํ„ฐํŽ˜์ด์ŠคB๋Š” ์ œ๊ณต๋ฐ›์€ ๋งค๊ฐœ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์ฒ˜๋ฆฌํ•œ ํ›„ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด.

ex) Consumer, Functon, Operatorํ•จ์ˆ˜ ๋””ํดํŠธ๋ฉ”์†Œ๋“œ ์ œ๊ณต

โœ…compose()

์ธํ„ฐํŽ˜์ด์ŠคAB์˜ method()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์šฐ์„  ์ธํ„ฐํŽ˜์ด์ŠคB๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ธํ„ฐํŽ˜์ด์ŠคA์˜ ๋งค๊ฐœ๊ฐ’์œผ๋กœ ์ œ๊ณต

์ธํ„ฐํŽ˜์ด์ŠคA๋Š” ์ œ๊ณต๋ฐ›์€ ๋งค๊ฐœ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์ฒ˜๋ฆฌํ•œ ํ›„ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด

์˜ˆ์‹œ) Function์˜ ์ˆœ์ฐจ์  ์—ฐ๊ฒฐ
public class FunctionAndThenComposeExample {
    public static void main(String[] args){
        Function<Member, Address> functionA;
        Function<Address, String> functionB;
        Function<Member, String> functionAB;
        String city;

        functionA = (m) -> m.getAddress();
        functionB = (m) -> m.getCity();
        
        // andThen() : ์ธํ„ฐํŽ˜์ด์ŠคA๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•œ ๋’ค ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธํ„ฐํŽ˜์ด์ŠคB๊ฐ€ ์ฒ˜๋ฆฌํ•œ ํ›„ ์ตœ์ข… ๊ฒฐ๊ณผ ๋ฆฌํ„ด
        functionAB = functionA.andThen(functionB);
        city = functionAB.apply(
                new Member("ํ™๊ธธ๋™", "gil", new Address("ํ•œ๊ตญ","์„œ์šธ"))
        );
        System.out.println("๊ฑฐ์ฃผ ๋„์‹œ : "+city);

        // compose() : ์ธํ„ฐํŽ˜์ด์ŠคB๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•œ ๋’ค ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธํ„ฐํŽ˜์ด์ŠคA๊ฐ€ ์ฒ˜๋ฆฌํ•œ ํ›„ ์ตœ์ข… ๊ฒฐ๊ณผ ๋ฆฌํ„ด
        functionAB = functionB.compose(functionA);
        city = functionAB.apply(
                new Member("ํ™๊ธธ๋™", "gil", new Address("ํ•œ๊ตญ","์„œ์šธ"))
        );
        System.out.println("๊ฑฐ์ฃผ ๋„์‹œ : "+city);
    }
}

and(), or(), negate() ๋””ํดํŠธ ๋ฉ”์†Œ๋“œ์™€ isEqual() ์ •์  ๋ฉ”์†Œ๋“œ

and() : ๋‘ Predicate๊ฐ€ ๋ชจ๋‘ true๋ฅผ ๋ฆฌํ„ดํ•˜๋ฉด ์ตœ์ข…์ ์œผ๋กœ true ๋ฆฌํ„ด

or() : ๋‘ Predicate ์ค‘ ํ•˜๋‚˜๋งŒ true๋ฅผ ๋ฆฌํ„ดํ•˜๋ฉด ์ตœ์ข…์ ์œผ๋กœ true ๋ฆฌํ„ด

negate() : ์›๋ž˜ Predicate์˜ ๊ฒฐ๊ณผ๊ฐ€ true๋ฉด false๋ฅผ ๋ฆฌํ„ด, false๋ฉด true๋ฅผ ๋ฆฌํ„ด

// 2์˜ ๋ฐฐ์ˆ˜
IntPredicate predicateA = a -> a % 2 == 0;

// 3์˜ ๋ฐฐ์ˆ˜
 IntPredicate predicateB = b -> b % 3 == 0;

 IntPredicate predicateAB;
 boolean result;

 // and()
 predicateAB = predicateA.and(predicateB);
 result = predicateAB.test(9);
 System.out.println("9๋Š” 2์™€ 3์˜ ๋ฐฐ์ˆ˜์ž…๋‹ˆ๊นŒ? : "+result);

 // or()
 predicateAB = predicateA.or(predicateB);
 result = predicateAB.test(9);
 System.out.println("9๋Š” 2 ๋˜๋Š” 3์˜ ๋ฐฐ์ˆ˜์ž…๋‹ˆ๊นŒ? : "+result);

 // negate()
 predicateAB = predicateA.negate();
 result = predicateAB.test(9);
 System.out.println("9๋Š” ํ™€์ˆ˜์ž…๋‹ˆ๊นŒ? : "+result);

 // isEquals()
 Predicate<String> predicate;

 predicate = Predicate.isEqual("JAVA8");
 System.out.println("JAVA8, null  :" +predicate.test(null));

 predicate = Predicate.isEqual(null);
 System.out.println("null, null  :" +predicate.test(null));

minBy(), maxBy() ์ •์ ๋ฉ”์†Œ๋“œ

o1๊ณผ o2๋ฅผ ๋น„๊ตํ•˜์—ฌ o1์ด ์ž‘์œผ๋ฉด ์Œ์ˆ˜๋ฅผ, o1๊ณผ o2๊ฐ€ ๋™์ผํ•˜๋ฉด 0์„ , o1์ด ํฌ๋ฉด ์–‘์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” compare()

BinaryOperator<Fruit> binaryOperator;
Fruit fruit;

// compare()
// (o1, o2) -> {return o1> o2 ? (+) : (-)
binaryOperator = BinaryOperator.minBy((o1, o2) -> Integer.compare(o1.price, o2.price));
fruit = binaryOperator.apply(new Fruit("๋”ธ๊ธฐ", 2000), new Fruit("์‚ฌ๊ณผ", 6000));
System.out.println("์‹ผ ๊ณผ์ผ : "+fruit.name);

binaryOperator = BinaryOperator.maxBy((o1, o2) -> Integer.compare(o1.price, o2.price));
fruit = binaryOperator.apply(new Fruit("๋”ธ๊ธฐ", 2000), new Fruit("์‚ฌ๊ณผ", 6000));
System.out.println("๋น„์‹ผ ๊ณผ์ผ : "+fruit.name);

๋ฉ”์†Œ๋“œ ์ฐธ์กฐ

// ๊ธฐ์กด ๋ฉ”์†Œ๋“œ ๋‹จ์ˆœํ˜ธ์ถœ
(left, right) -> Math.max(left, rigth);
// ๋ถˆํ•„์š”ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ
(left, right) -> Math::max;
โœ… ์ •์ ๋ฉ”์†Œ๋“œ์™€ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ
  • ์ •์ ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ > ํด๋ž˜์Šค :: ๋ฉ”์†Œ๋“œ ex)Calculator :: staticMethod;
  • ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ > ์ฐธ์กฐ๋ณ€์ˆ˜ :: ๋ฉ”์†Œ๋“œ ex) calculator :: instanceMethod;
public class Calculator {
    public static int staticMethod(int x, int y){
        return x+y;
    }

    public int instanceMethod(int x, int y){
        return x+y;
    }
}    
IntBinaryOperator operator;

// ์ •์ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
operator = (x,y) -> Calculator.staticMethod(x,y);
System.out.println(operator.applyAsInt(5,7));
// ์ •์ ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ
operator = Calculator :: staticMethod;
System.out.println(operator.applyAsInt(1,2));

// ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
Calculator calculator = new Calculator();
operator = (x,y) -> calculator.instanceMethod(x, y);
System.out.println(operator.applyAsInt(5,7));
// ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ
operator = calculator ::instanceMethod;
System.out.println(operator.applyAsInt(1,3));
โœ… ์ƒ์„ฑ์ž ์ฐธ์กฐ
public class Member {
    private String name;
    private String id;
   
    public Member(String id){
        System.out.println("String id ์‹คํ–‰");
        this.id = id;

    }
    public Member(String name, String id){
        System.out.println("String id, String name ์‹คํ–‰");
        this.name = name;
        this.id = id;
    }
}

// void main ํ˜ธ์ถœ
Function<String, Member> function1 = Member :: new;
Member member1 = function1.apply("angel1");

BiFunction<String, String, Member> function2 = Member :: new;
Member member2 = function2.apply("name", "angel2");

โ€ป [์ด๊ฒƒ์ด ์ž๋ฐ”๋‹ค ์‹ ์šฉ๊ถŒJava ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ •๋ณต2] ํ•ด๋‹น ์ฑ…์„ ์ฐธ๊ณ ํ•˜๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

profile
Java Web Developer๐Ÿ˜Š

0๊ฐœ์˜ ๋Œ“๊ธ€