Java

๋žŒ๋‹คLambda

voider 2020. 9. 9. 11:01

๐Ÿ“š ์ž๋ฐ”์˜ ์ •์„์„ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

โ–ช ๋žŒ๋‹ค์‹Lambda Expression

์ž๋ฐ”๋Š” ๋‘ ๋ฒˆ์˜ ํฐ ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ๋‹ค. JDK1.5์˜ ์ง€๋„ค๋ฆญ์Šค. JDK1.8์˜ ๋žŒ๋‹ค.
๋žŒ๋‹ค์˜ ๋“ฑ์žฅ์œผ๋กœ ๊ฐ์ฒด์ง€ํ–ฅ์–ธ์–ด๋ฅผ ๋„ˆ๋จธ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๊ฐ€ ๊ฐ€์ง„ ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ฐ–์ถ”๊ฒŒ ๋˜์—ˆ๋‹ค.
๋งํ•˜์ž๋ฉด ๋น„๋กœ์†Œ ํ˜ธ๋ชจ ์‚ฌํ”ผ์—”์Šค์˜ ๊ธธ์— ์ ‘์–ด๋“  ๊ฒƒ์ผ๊นŒ?

๋žŒ๋‹ค์‹์ด๋ž€ ๊ฐ„๋‹จํžˆ ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜์˜ ์‹์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.
ํ•จ์ˆ˜๋ฅผ ๊ฐ„๋žตํ•˜๋ฉด์„œ๋„ ๋ช…ํ™•ํ•œ ์‹์œผ๋กœ ํŽธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์„œ๋“œ๋ฅผ ๋žŒ๋‹ค์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†์–ด์ง„๋‹ค. ๊ทธ๋ž˜์„œ ์ต๋ช… ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ์“ฐ๋Š” ๊ฑฐ๋ƒ๋ฉด.

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

๋‘ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›๊ณ  ํฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” max๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค.
์ด๊ฒƒ์„ ๋žŒ๋‹ค๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

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

//๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์ด ๊ฐ™์€ ๊ฒฝ์šฐ ํƒ€์ž…์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.
(a,b) -> a > b ? a:b

์ด๋ ‡๊ฒŒ ๋ฐ˜ํ™˜๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ return๋ฌธ์„ ์‹์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ returnํ•œ๋‹ค.
๋ฌธ์žฅ์ด ์•„๋‹ˆ๋ผ '์‹expression'์ด๋ฏ€๋กœ ';'์„ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค.
๋งŒ์•ฝ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜๋ผ๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ์‹ธ๋Š” ๊ด„ํ˜ธ๋„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

i -> i * i

๋ฉ”์„œ๋“œ -> ๋žŒ๋‹ค

Method Lambda
int max(int a, int b) {
return a > b ? a : b ;
}
(a,b)-> a > b ? a : b
void 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)
int sumArr(int[] arr) {
int sum=0;
for(int i : arr){sum += i;}
return sum;
}
(int[] arr) -> {
int sum = 0;
for(int i : arr){ sum += i;}
return sum;
}

โ–ช ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์ŠคFunctional Interface

๋žŒ๋‹ค๋Š” ์ต๋ช… ํด๋ž˜์Šค ๊ฐ์ฒด์™€ ๋™๋“ฑํ•˜๋‹ค.

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

์ด ์ฝ”๋“œ์™€

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

์ด ์ฝ”๋“œ๊ฐ€ ๋™๋“ฑํ•˜๋‹ค๋Š” ๋œป์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋žŒ๋‹ค๋กœ ์ •์˜๋œ ์ต๋ช… ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœํ•˜๋ ค๋ฉด ๊ฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•  ์ฐธ์กฐ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

ํƒ€์ž… f = (int a, int b) -> a > b ? a : b;

์–ด๋–ค ํƒ€์ž…์ด ์˜ฌ ์ˆ˜ ์žˆ์„๊นŒ?

์กฐ๊ฑด

  • ๋žŒ๋‹ค์‹๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    ๊ทธ๋ž˜์•ผ๋งŒ ์ฐธ์กฐ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋žŒ๋‹ค์‹์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
interface MyFuntion {
    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 big = f.max(5,3);

์œ„ ์ต๋ช…ํด๋ž˜์Šค๋ฅผ ๋žŒ๋‹ค๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

MyFunction f = (a, b) -> a > b ? a : b;    
int big = f.max(5,3);    //๋ฉ”์„œ๋“œ ํ˜ธ์ถœ

์ต๋ช…๊ฐ์ฒด๋ฅผ ๋žŒ๋‹ค๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ๋žŒ๋‹ค์‹๋„ ์‹ค์ œ๋กœ๋Š” ์ต๋ช… ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์„ ์–ธ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ ๋‹ค์Œ ๋žŒ๋‹ค๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ๊ธฐ์กด์˜ ์ž๋ฐ” ๊ทœ์น™์„ ์–ด๊ธฐ์ง€ ์•Š์œผ๋ฉด์„œ ์ž์—ฐ์Šค๋Ÿฝ๋‹ค.
๊ทธ๋ž˜์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋žŒ๋‹ค๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ์ด๋Ÿฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šคfunctional interface๋ผ๊ณ  ํ•œ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค ์„ ์–ธ๋ถ€์— ๋‹จ์ˆœํžˆ ์–ด๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ ๋ง๊ณ ๋Š” ๊ธฐ์กด๊ณผ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค. ์œ„ ์งง์€ ์˜ˆ์ œ์—์„œ ๋ณด์•˜๋“ฏ์ด ์—†์–ด๋„ ์ƒ๊ด€์€ ์—†์ง€๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ํ™•์ธํ•ด์ฃผ๋ฏ€๋กœ ๋ถ™์ด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

@FunctionalInterface

  • ์˜ค์ง ํ•˜๋‚˜์˜ ์ถ”์ƒ๋ฉ”์„œ๋“œ๋งŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ์™€ ๋žŒ๋‹ค๋ฅผ 1:1๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ.

  • static๋ฉ”์„œ๋“œ์™€ default๋ฉ”์„œ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” ์ œ์•ฝ์ด ์—†๋‹ค.

์ต๋ช… ํด๋ž˜์Šค์™€ ๋žŒ๋‹ค ๋น„๊ต

//์ต๋ช… ํด๋ž˜์Šค
Collections.sort(list, new Comparator<String>() {
    public int compare(String s1, String s2) {
        return s2.compareTo(s1);
    }
}

//๋žŒ๋‹ค
Collections.sort(list, (s1, s2) -> s2.compareTo(s1))

FunctionalInterfaceํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜ํƒ€์ž…

  • ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šคํƒ€์ž…์ด๋ฉด, ํ˜ธ์ถœ ์‹œ ๋žŒ๋‹ค(๋˜๋Š” ์ฐธ์กฐ๋ณ€์ˆ˜)๋ฅผ ์ธ์ž๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

    @FunctionalInterface 
    interface MyFunction {
        void myMethod();    //์ถ”์ƒ๋ฉ”์„œ๋“œ
    }
    
    ...
    void aMethod(MyFunction f) {
        f.myMethod();
    }
    -----------------------------------------
    //๊ตฌํ˜„๊ณผ ๋™์‹œ์— ํ˜ธ์ถœ
    aMethod(() -> System.out.println("myMethod()"));    
  • ๋ฐ˜ํ™˜ํƒ€์ž…์ด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šคํƒ€์ž…์ด๋ผ๋ฉด, ๋žŒ๋‹ค๋ฅผ returnํ•œ๋‹ค.

    MyFunction myMethod() {
        //๋ฐ˜ํ™˜ํƒ€์ž…์ด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋ฉด, ๋žŒ๋‹ค๋ฅผ returnํ•œ๋‹ค.
        return () -> System.out.println("myMethod()");
    }

โ™ป ๋žŒ๋‹ค์‹ ํƒ€์ž…๊ณผ ํ˜•๋ณ€ํ™˜

๋žŒ๋‹ค์˜ ํƒ€์ž…์ด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋‹ค๋งŒ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋žŒ๋‹ค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๋‹ค. ๋žŒ๋‹ค์‹์€ ์ต๋ช… ๊ฐ์ฒด์ด๋ฏ€๋กœ ํƒ€์ž…์ด ์—†๋‹ค.

MyFunction f = (MyFunction)(() ->{}); //์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…๊ณผ, ๋žŒ๋‹ค ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฏ€๋กœ ํ˜•๋ณ€ํ™˜ ํ•„์š”

ํ•˜์ง€๋งŒ ์—ญ์‹œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋Œ€์‹  ํ•ด์ค€๋‹ค.
๋žŒ๋‹ค๋Š” ์ด๋ฆ„๋งŒ ์—†์„ ๋ฟ ๊ฐ์ฒด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Objectํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•  ์ˆ˜ ์—†๋‹ค.
๊ตณ์ด ํ•˜๋ ค๋ฉด ๋จผ์ € MyFunction์œผ๋กœ ํ˜•๋ณ€ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

Object obj = ((Object)(MyFunction))(()->{})).toString();

โ†— ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋žŒ๋‹ค์‹

๋žŒ๋‹ค์‹๋„ ์ต๋ช… ๊ฐ์ฒด์ด๋ฏ€๋กœ ์™ธ๋ถ€์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์€ ์ต๋ช…ํด๋ž˜์Šค์™€ ๋™์ผํ•˜๋‹ค.

package com.javaex.lambda;

public class LambdaEx3 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();

        inner.method(100);
    }
}


@FunctionalInterface
interface MyFunction{
    void myMethod();
}

class Outer {
    int val = 10;   //Outer.this.val

    class Inner {
        int val = 20;   //this.val

        void method(int i) {    //(final int i)
            int val = 30;   //final int val = 30;
//            i = 10;       //final์ด๋ฏ€๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€

            MyFunction f = () -> {
                System.out.println("i : "+ i);
                System.out.println("val : " + val);
                System.out.println("this.val : " + ++this.val);
                System.out.println("Outer.this.val : " + Outer.this.val);
            };

            f.myMethod();
        }
    }
}

๋žŒ๋‹ค์‹ ๋‚ด์—์„œ ์ฐธ์กฐํ•˜๋Š” ์ง€์—ญ๋ณ€์ˆ˜๋Š” final์ด ๋ถ™์ง€ ์•Š์•˜์–ด๋„ final๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.

๐Ÿ“ฆ java.util.function

๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ๋Œ€๊ฐœ ๋น„์Šทํ•˜๋‹ค.

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๊ฑฐ๋‚˜, ํ•˜๋‚˜ ๋˜๋Š” ๋‘ ๊ฐœ
  • return์€ ์žˆ๊ฑฐ๋‚˜ ์—†๊ฑฐ๋‚˜
    ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ˜ํ™˜ํƒ€์ž…๋„ ๋ฌธ์ œ ๋˜์ง€ ์•Š๋Š”๋‹ค.

java.util.package์—๋Š” ์ž์ฃผ ์“ฐ์ด๋Š” ํ˜•์‹์˜ ๋ฉ”์„œ๋“œ๋“ค์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค. ๋Š˜ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์“ฐ๋Š” ๊ฒƒ๋ณด๋‹ค ์ด ํŒจํ‚ค์ง€์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ํ†ต์ผ, ์žฌ์‚ฌ์šฉ์„ฑ, ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ๋ชจ๋‘ ์ข‹๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

์ด๋ฏธ์ง€ ์ถœ์ฒ˜ : ์ž๋ฐ”์˜ ์ •์„

4๊ฐœ์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ๋‹ค.

์กฐ๊ฑด์‹์—์„œ Predicate

Predicate๋Š” Function์˜ ๋ณ€ํ˜•์ด๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์ด boolean์ด๋ผ๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค. ์ˆ˜ํ•™์—์„œ true ๋˜๋Š” false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ Predicate๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์กฐ๊ฑด์‹์„ ๋žŒ๋‹ค์‹์œผ๋กœ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

Predicate<String> isEmptyStr = s -> s.length() == 0;
String s = "";

if(isEmptyStr.test(s)) {    //if(s.length() == 0)
    ....
}

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ธ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

์ด๋ฏธ์ง€ ์ถœ์ฒ˜ : ์ž๋ฐ”์˜ ์ •์„

BiSupplier๊ฐ€ ์—†๋Š” ์ด์œ ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์—†๊ณ  ๋ฐ˜ํ™˜๊ฐ’๋งŒ ์กด์žฌํ•˜๋Š”๋ฐ ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งŒ์•ฝ ์ด ์™ธ์— ๋‘ ๊ฐœ ์ด์ƒ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ง์ ‘ ๋งŒ๋“ค์–ด ์จ์•ผ ํ•œ๋‹ค.

@FunctionalInterface
interface TriFunction<T,U,V,R> {
    R apply(T t, U u, V v);
}

UnaryOperator์™€ BinaryOperator

Function์˜ ๋˜ ๋‹ค๋ฅธ ๋ณ€ํ˜•์ด๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…๊ณผ ๋ฐ˜ํ™˜ํƒ€์ž…์ด ์ผ์น˜ํ•œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค.

CollectionFramework & Functional Interface

์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์— ์„ ์–ธ๋œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ์ค‘ ์ผ๋ถ€๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Interface Method ์„ค๋ช…
Collection boolean removeAll(Predicate<E> filter) ์กฐ๊ฑด์— ๋งž๋Š” ์š”์†Œ ์‚ญ์ œ
List void replaceAll(UnaryOperator<E> operator) ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ ๋Œ€์ฒด
Iterable void forEach(Consumer<T> action) ๋ชจ๋“  ์š”์†Œ์— ์ž‘์—… action์„ ์ˆ˜ํ–‰
Map V compute(K key, BiFunction<K,V,V> f)
V computeIfAbsent(K key, Function<K,V> f)
V computeIfPresent(K key Function<K,V> f)
V merge(K key, V value, BiFunction<V,V,V> f)
void forEach(BiConsumer<K,V> action)
void replaceAll(BiFunction<K,V,V> f)
์ง€์ •ํ•œ ํ‚ค์˜ ๊ฐ’์— ์ž‘์—… f๋ฅผ ์ˆ˜ํ–‰
ํ‚ค๊ฐ€ ์—†์œผ๋ฉด ์ž‘์—… f ์ˆ˜ํ–‰ ํ›„ ์ถ”๊ฐ€
์ง€์ •ํ•œ ํ‚ค๊ฐ€ ์žˆ์„ ๋•Œ ์ž‘์—… f ์ˆ˜ํ–‰
๋ชจ๋“ ์š”์†Œ์— ๋ณ‘ํ•ฉ์ž‘์—… f๋ฅผ ์ˆ˜ํ–‰
๋ชจ๋“  ์š”์†Œ์— ์ž‘์—… action์„ ์ˆ˜ํ–‰
๋ชจ๋“  ์š”์†Œ์— ์น˜ํ™˜์ž‘์—… f๋ฅผ ์ˆ˜ํ–‰
package com.javaex.lambda;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LambdaEx4 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 10; i ++) {
            list.add(i);
        }

        //list์˜ ๋ชจ๋“  ์š”์†Œ ์ถœ๋ ฅ
        list.forEach(i -> System.out.println(i));

        //list์—์„œ 2 ๋˜๋Š” 3์˜ ๋ฐฐ์ˆ˜ ์ œ๊ฑฐ
        list.removeIf(x -> x%2==0 || x%3==0);   //removeIf(Predicate<E> filter)
        System.out.println(list);

        //list์˜ ๊ฐ ์š”์†Œ์— 10์„ ๊ณฑํ•œ๋‹ค.
        list.replaceAll(i -> i*10); //void replaceAll(UnaryOperator<E> operator)
        System.out.println(list);

        Map<String, String> map = new HashMap<>();
        map.put("1", "1");
        map.put("2", "2");
        map.put("3", "3");
        map.put("4", "4");

        //void forEach(BiConsumer<K,V> action)
        map.forEach((k,v) -> System.out.println("["+k+","+v+"]"));
    }
}

๊ทธ๋ฆฌ๊ณ  ์•ž์—์„œ ์„ค๋ช…ํ•œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋‹ค.
์‰ฌ์šด ๋“ฏ ํ—ท๊ฐˆ๋ ค์„œ ์ฃผ์„์„ ๊ผผ๊ผผํžˆ ๋‹ฌ์•˜๋‹ค.

package com.javaex.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class LambdaEx5 {
    public static void main(String[] args) {
        /*Suplier<T>๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์—†๊ณ  ๋ฐ˜ํ™˜๊ฐ’๋งŒ ์žˆ๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋‹ค.
        ์ถ”์ƒ๋ฉ”์„œ๋“œ T get()๊ฐ€ 1 ~ 100 ์‚ฌ์ด ์ž„์˜์˜ ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค.*/
        Supplier<Integer> supplier = () -> (int)(Math.random()*100) + 1;

        /*Consumer<T>๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ ์žˆ๊ณ  ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋‹ค.
        * void accept(T t)๋ฅผ ์ž…๋ ฅ ๋ฐ›์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
        * */
        Consumer<Integer> consumer = i -> System.out.print(i + ",");

        /*
        * Predicate<T>๋Š” ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ณ , boolean์„ returnํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋‹ค.
        * boolean test(T t)๋ฅผ ์ž…๋ ฅ ๋ฐ›์€ t๊ฐ€ 2์˜ ๋ฐฐ์ˆ˜(i%2==0)๋ผ๋ฉด true ์•„๋‹ˆ๋ผ๋ฉด false๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
        * */
        Predicate<Integer> predicate = i -> i%2==0;

        /*
        * Function<T,R>์€ ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜T๋ฅผ ๋ฐ›์•„ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผR๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
        * R apply(T t)๋ฅผ ์ž…๋ ฅ ๋ฐ›์€ t์˜ ์ผ์˜ ์ž๋ฆฌ๋ฅผ ์—†์• ๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
        * */
        Function<Integer, Integer> function = i -> i/10*10; //i์˜ ์ผ์˜ ์ž๋ฆฌ๋ฅผ ์—†์•ค๋‹ค.

        List<Integer> list = new ArrayList<>();

        //list์— 10๊ฐœ์˜ ๋‚œ์ˆ˜๋ฅผ ์ €์žฅํ•œ๋‹ค.
        makeRandomList(supplier, list);
        //ํ™•์ธ
        System.out.println(list);

        //list์— ์ €์žฅ๋œ ๊ฐ’ ์ค‘์—, 2์˜ ๋ฐฐ์ˆ˜์ธ ๊ฒƒ๋งŒ ์ถœ๋ ฅํ•œ๋‹ค
        printEvenNum(predicate, consumer, list);

        //list์— ์ €์žฅ๋œ ๊ฐ’๋“ค์˜ ์ผ์˜ ์ž๋ฆฌ๋ฅผ ์—†์• ์„œ List๋ฅผ returnํ•˜๋Š” ๋ฉ”์„œ๋“œ
        List<Integer> newList = doSomething(function, list);
        System.out.println(newList);

    }

    static <T> List<T> doSomething(Function<T,T> f, List<T> list) {
        List<T> newList = new ArrayList<>();

        /*list์— ์ €์žฅ๋œ ๊ฐ’์„ i์— ๋Œ€์ž…ํ•œ๋‹ค.
        * i์— ๋Œ€์ž…๋œ ๊ฐ’์—์„œ ์ผ์˜ ์ž๋ฆฌ๋ฅผ ์—†์• ๊ณ f.apply(i) newList์— ์ €์žฅํ•œ๋‹ค.
        * */
        for (T i : list) { newList.add(f.apply(i)); }

        //list์˜ ๊ฐ’๋“ค์„ ์ผ์˜ ์ž๋ฆฌ๋งŒ ์—†์•ค ์ฑ„๋กœ return
        return newList;
    }


    static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
        System.out.print("[");

        /*
        * ์ž…๋ ฅ list์˜ ๊ฐ’์„ ํ•˜๋‚˜์”ฉ i์— ๋Œ€์ž…ํ•œ๋‹ค.
        * ๊ทธ ์ค‘์— 2์˜ ๋ฐฐ์ˆ˜์ธ ๊ฒƒ๋งŒ Consumer<T> c์— ๋‹ด๋Š”๋‹ค.
        * accept()๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ์ธ์ž๋กœ ๋ฐ›์€ i๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
        * */
        for (T i : list ) {
            if (p.test(i)) {
                c.accept(i);
            }
        }
        System.out.println("]");
    }

    //์ž…๋ ฅ๋ฐ›์€ list์— ๋‚œ์ˆ˜ ์—ด ๊ฐœ๋ฅผ ์ €์žฅํ•œ๋‹ค.
    static <T> void makeRandomList(Supplier<T> s, List<T> list) {
        for (int i=0; i<10; i++) {
            /*
            * ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉด์„œ
            * s.get()์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค
            * 1 ~ 100 ์‚ฌ์ด ์ž„์˜์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
            * */
            list.add(s.get());
        }
    }
}

๊ธฐ๋ณธํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

์œ„ ์˜ˆ์ œ๋ฅผ ๊ธฐ๋ณธํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฐ”๊พผ ๊ฒƒ์ด๋‹ค.
์ฃผ์„์€ ์œ„์— ์ƒ์„ธํ•˜๊ฒŒ ๋‹ฌ์•˜์œผ๋ฏ€๋กœ ์ƒ๋žตํ•œ๋‹ค.

package com.javaex.lambda;

import java.util.Arrays;
import java.util.function.IntConsumer;
import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.IntUnaryOperator;

public class LambdaEx6 {
    public static void main(String[] args) {
        IntSupplier s = () -> (int)(Math.random() * 100) + 1;
        IntConsumer c = i -> System.out.print(i + ",");
        IntPredicate p = i -> i%2==0;
        IntUnaryOperator op = i -> i/10*10; //์ผ์˜ ์ž๋ฆฌ ์—†์•ค๋‹ค.

        int[] arr = new int[10];

        makeRandomList(s, arr);
        System.out.println(Arrays.toString(arr));
        printEvenNum(p, c, arr);
        int[] newArr = doSomething(op, arr);
        System.out.println(Arrays.toString(arr));
    }

    static void makeRandomList(IntSupplier s, int[] arr) {
        for (int i = 0; i<arr.length;i++){
            arr[i] = s.getAsInt();  //get์ด ์•„๋‹ˆ๋ผ getAsInt()
        }
    }
    static void printEvenNum (IntPredicate p, IntConsumer c, int[] arr) {
        System.out.print("[");
        for (int i : arr ) {
            if (p.test(i)) {
                c.accept(i);
            }
        } //for
        System.out.print("]");
        System.out.println();
    } // end printEvenNum

    static int[] doSomething(IntUnaryOperator op, int[] arr) {
        int[] newArr = new int[arr.length];

        for (int i = 0; i < newArr.length; i++) {
            newArr[i] = op.applyAsInt(arr[i]);  //apply()์•„๋‹˜
        }

        return newArr;
    }


}

'Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

์˜ˆ์™ธ์ฒ˜๋ฆฌ  (0) 2020.09.10
Stream  (0) 2020.09.10
์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œGeneric Method  (0) 2020.09.09
์™€์ผ๋“œ์นด๋“œ  (0) 2020.09.09
์ œ๋„ค๋ฆญ ํด๋ž˜์ŠคGenerics Class  (0) 2020.09.09