Java의 Lamda

zihooy·2023년 5월 9일
0

Java Programming

목록 보기
18/21
post-thumbnail

Java의 기본 개념 중 Lamda에 대해 알아보자.

🏹 람다의 기본 규칙

람다 함수는 익명 함수(Anonymous functions)를 의미하며, 기본꼴은 ()->{}이다.

람다의 규칙 3가지를 이해하면
1. 람다는 매개변수 / 화살표(->) / 함수몸체로 사용 가능
2. 함수몸체가 단일 실행문이면 괄호{} 생략 가능
3. 함수몸체가 return문으로만 구성되어 있는 경우 괄호{} 생략 불가

🏹 코드를 통한 람다 이해

아래의 코드를 천천히 이해해보자.

interface Test01{
    void f1();
}
interface Test02 {
    void f1(int num);
}
interface Test03 {
    void f1(int num, String s);
}
interface Test04 {
    int f1();
}
interface Test05 {
    int f1(int num);
}

위와 같이 인수와 return 타입이 다른 5가지의 interface를 구현해보며 람다식을 적용해보자.

기본식

public class HelloApplication {
    public static void main(String[] args) {

        Test01 t1 = new Test01() {
            @Override
            public void f1() {
                System.out.println(1);
            }
        };
        t1.f1();
        // 위의 코드를 람다 식으로 표현하기
        // Test t2 = () -> {}: 람다의 기본 꼴
        Test01 t2 = () -> {
            System.out.println(2);
        };
        t2.f1();

위 2가지의 결과가 동일하다.
람다를 활용하면, 간단하게 코드를 작성할 수 있다.

인수가 존재하는 경우

        //인수가 있을 때 람다 사용법
        //Test02 t3 = (n) -> {
        //    System.out.println(n);
        //};
        
        //인수 전달이 1개 전달 일때만... ()를 생랼할 수 있다.
        //일반적으로 생략한다.
        Test02 t3 = n -> {System.out.println(n);};
        t3.f1(100);

        //인수 전달이 2개여서 ()를 생략할 수 없다.
        Test03 t4 = (n, s) -> {
            System.out.println(n+s);
        };
        t4.f1(100, "호랑이");

위의 코드는 interface에 인수가 있는 경우이다.
인수가 1개인 경우에만 ()를 생략할 수 있다.

return값이 존재하는 경우

        //return 값이 있는 경우
        //Test04 t5 = ()->{
        //    return 1000;
        //};
        
        //한 문장일 때는 return과 {} 생략 가능, 선호됨
        Test04 t5 = ()->1000;
        System.out.println(t5.f1());

        //return값, 인수가 있는 경우
        Test05 t6 = n -> n*2;
        System.out.println(t6.f1(100));
    }

}

위의 코드는 interface에 return값이 있는 경우이다.
단문장인 경우 return과 {}을 생략할 수 있고,
인수가 1개인 경우에는 ()을 생략할 수 있기 때문에 코드가 굉장히 간단해진다.

🏹 람다를 통한 익명 객체 생성

interface Test01{
    void f1();
}
interface Test02{
    int f1();
}
class Tiger {
    void f2(Test01 ttt){
        ttt.f1();
    }
    void f3(Test02 ttt) {
        System.out.println(ttt.f1());
    }

}
public class HelloApplication {
    public static void main(String[] args) {
        Test01 t1 = ()->{
            System.out.println(1);
        };
        t1.f1();

        Test02 t2 = ()-> 100;
        System.out.println(t2.f1());

        Tiger t = new Tiger();
        
        //원래 코드
        t.f2(new Test01() {
            @Override
            public void f1() {
                System.out.println("확인1");
            }
        });
        //람다사용
        t.f2(()->{
            System.out.println("확인2");
        });
        
        //원래 코드
        t.f3(new Test02() {
            @Override
            public int f1() {
                System.out.println("확인3");
                return 100;
            }
        });
        //람다사용
       t.f3(()->100);
    }
}

위 코드를 살펴보면 람다를 사용할 때 코드가 훨씬 간편해짐을 확인할 수 있다.

만약 이해가 잘 되지 않는다면, 앞 부분부터 한번 더 읽고 오기를 추천한다.
처음에는 낯설 수 있지만, 한번 이해하면 매우 편리하게 사용 가능할 것이다.

여기까지 잘 이해했다면, 아래의 코드를 한번 살펴보자.

interface Test01{
    void f1();
}
class Tiger{
    Test01 f2(Test01 t){
        return ()->{
            System.out.println(2);
        };
    }
}
public class HelloApplication {
    public static void main(String[] args) {
        Tiger t = new Tiger();
        t.f2(()->{
            System.out.println(1);
        }).f1();
    }
}

main을 살펴보면, Tiger 객체를 생성하고, f2()를 호출한다.
f2()는 Test01 객체를 인수로 받기 때문에 람다를 활용해 익명의 Test01 객체를 생성하였음을 알 수 있다.
또한 Test01는 interface로 f1()을 반드시 구현해주어야 한다.
따라서 위와 같은 코드가 나오게 된 것이다.

🏹 람다를 잘 이해 했는지 check !

interface Test01{
    int f1(int num);
}

class Tiger{
    Test01 f2(Test01 t){
        t.f1(88);
        return n-> 77;
    }
}

public class HelloApplication {
    public static void main(String[] args) {
        Tiger t = new Tiger();
        t.f2(n-> 66).f1(99);
    }
}

위의 코드가 이해된다면, 람다를 잘 이해했다고 볼 수 있다!

profile
thisIsZihooLog

0개의 댓글