본문 바로가기

Coding Language/Java

[Java] Lambda 식을 이용하여 코드 줄이기

[해당 포스트는 개인적으로 공부를 하고 차후에 참고용으로 하고자 작성한 것입니다.

따라서 잘못된 부분이나 부족한 부분이 있을 수 있기에 참고하시기 바랍니다.]

 

이번 Java 실습을 하면서 Lambda 방식에 대해 언급이 되어 우연찮게 알게 되었다.

 

기존엔 C++이나 Python에선 Lambda방식을 주로 사용하였으나, Java에서 사용하는 건 처음이라 많이 복잡하여 정리하고자 한다.

 

람다식이란?

Java8 버전부터 Lambda Expressions를 지원하게 되었다고 한다. Interface를 통해 생성한 Method를 Class를 통해 implements 하지 않으며 간략하게 Method를 구현할 수 있다.

우선 Lambda 방식은 익명 함수를 생성하기 위한 방식으로 Java와 같은 객체 지향 언어보다는 C 같은 함수 지향 언어에 가깝다. 또한 Method를 매개 변수처럼 사용할 수 있기에 많이 생소할 수 있다.

 

다음은 Lambda 식을 사용하기 위한 조건이다.

  • 함수를 따로 만들지 않고 코드 한 줄에 함수를 쓰는 '익명 함수' 방식을 이용하여 호출한다.
  • 함수의 실행이 외부의 상태를 변경시키지 않는 함수, 즉 '순수한 함수' 형태를 이용하여 항상 동일한 값을 반환한다.
  • 함수형 언어에서는 함수도 하나의 인자로 취급하여 사용한다. 즉 '일급 객체'로 간주하여 '고계 함수'형태로 사용한다.

여기서 의문점이 들 것이다. Java에서 메서드를 인자로 전달한다고?

Java의 Method는 일급 함수가 아니므로, 다른 메서드에 인자 형태로 전달할 수 없었다. Method는 단지 객체와 행위를 정의하거나 변경하는 역할만 하였다.

 

그러나 Java8 에서부터 함수형 인터페이스라는 개념을 도입하게 되었고, 위의 조건에 위배되지 않으며 Lambda로 표현할 수 있게 되었다.

 

다음은 Lambda 식을 사용하는 방법이다.

 

(매개변수 1, 매개변수 2,...) -> {실행문...}

 

상당히 애매모호하다. Java를 사용할 때 Arrow(->)를 사용한 적이 없다 보니 정말 뭔 소린지를 몰랐다.

짤막한 예제를 보면서 어떻게 저러한 형태로 줄일 수 있는지 확인해보자.

 

우선 하나의 인터페이스를 생성하자.

1
2
3
interface Apple{
    void func1();
}

해당 인터페이스를 이용하여 익명 함수를 구현하도록 할 것이다. 다음은 Main을 생성하도록 하자. 첫 번째 예시에선 단순히 익명 객체를 생성하여 실행하도록 하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Lambda {
    public static void main(String args[]) {
        Apple a = new Apple() {
            
            @Override
            public void func1() {
                // TODO Auto-generated method stub
                System.out.println("Apple func1 Call.");
            }
        };
        
        a.func1();
    }
}
 
 
Apple Interface를 익명객체를 통해 func1을 구현하여 출력하도록 하였다. 하나의 Method를 구현하기 위해서 코드가 8줄이 사용되었다. 이것을 한 줄로 줄일 수 있는 기법이 Lambda 방식이다. 이제 Lambda 방식으로 코드를 단순하게 작성을 해보자.
1
2
3
4
5
6
7
8
9
public class Lambda {
    public static void main(String args[]) {
        Apple b = () -> {
            System.out.println("Apple func1 b Call.");
        };
 
        b.func1();
    }
}
 

8줄이나 썼던 명령문을 3줄로 줄일 수 있는 것을 볼 수 있다. 단순히 Scope앞에 Shift Line만 제거하면 1줄로 표현할 수 있다. 그렇다면 이번엔 어떠한 방식을 이용하여 코드가 간략해졌는지 순차적으로 알아보도록 하자.

1
2
3
4
5
Apple a = /* new Apple */() -> {
            // public void func1() {
            System.out.println("Apple func1 a Call.");
            // }
        };
 

 

  1. 기존 익명 객체를 생성할 때 입력한 "new Apple"까지 제거한다.
  2. 구현했던 함수명과 Scope를 제거한다.
  3. 끝.

다음 시간엔 인자를 받는 Method에선 어떻게 처리하는지에 대해 기록하도록 하겠다.