Java/Theory

[Java/Theory]29. Lambda Expression

양승길 2016. 9. 18. 15:38

[Java/Theory]29. Lambda Expression

출처 : 

https://en.wikipedia.org/wiki/Lambda_expression

http://jdm.kr/blog/181

https://www.tutorialspoint.com/java8/java8_lambda_expressions.htm


정의 

식별자(identifier)로 binding되지 않은채 정의된 함수. 

Java 8 부터 지원하는 표현식으로서, 함수형 프로그래밍을 도입한다.

가독성과 간편성의 목적을 두고있고, 객체지향의 큰 특징인 다형성을 활용했다.


특징

유형 정의, 괄호와 중괄호((), {}), 반환값 정의에 독립적.

차후 예제에서 확인한다.

   

기존 사용법.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package example;
 
public class PreviousThread {
    
    public static void main(String args[]){
        
        Thread thread = new Thread (new Runnable(){
 
            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("There is no rule without exception.");
            } // end of run
            
        }); // end of definition to thread variable
        
        thread.start();
        
    } // end of main
    
// end of PreviousThread
cs


기본적인 사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package example;
 
public class LambdaThread {
 
    public static void main(String args[]){
        
        Thread thread = new Thread(() ->{
            System.out.println("There is no rule without exception.");
        });
        
        thread.start();
        
    } // end of main
    
}// end of LambdaThread
cs


주의점

Lambda Expression을 활용하기 위해서 대상 Interface는 abstract method를 단 하나만 보유해야된다. 또한 Lambda Expression을 사용하는 목적으로 설계된 Interface는 정의할 때 Annotation을 이용하여 명시하도록 한다. 물론 표기하지 않아도 되나, 여러가지의 오류를 아래의 예제로 두도록 하겠다. 이는 Compiler 수준에서 오류를 확인 할 수 있다는 것을 알 수있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package example;
 
public class ExOfLambda {
 
    interface Cal{
        int add(int a, int b);
        int sub(int a, int b);
    }
    
    public static void main(String args[]){
        
        // Syntax Error 
        // The target type of this expression must be a function interface
        Cal cal = (int a, int b) -> a+b;
        
    } // end of main
    
}// end of ExOfLambda
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package example;
 
public class ExOfLambda {
 
    // Syntax Error
    // Invalid '@FunctionalInterface' annotation; ExOfLambda.Cal is not a functional interface.
    @FunctionalInterface
    interface Cal{
        int add(int a, int b);
        int sub(int a, int b);
    }
    
    public static void main(String args[]){
        
        // Syntax Error 
        // The target type of this expression must be a function interface
        Cal cal = (int a, int b) -> a+b;
        
    } // end of main
    
}// end of ExOfLambda
 
cs


올바른 예제는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package example;
 
public class ExOfLambda {
 
    @FunctionalInterface
    interface Cal{
        int add(int a, int b);
    }
    
    public static void main(String args[]){
        
        Cal cal = (int a, int b) -> a+b;
        
        System.out.println(cal.add(12));
        
    } // end of main
    
}// end of ExOfLambda
 
cs


특징을 이용한 활용법.

유형 정의, 괄호와 중괄호((), {}), 반환값 정의에 독립적이라 하면 활용하는 예제는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package example;
 
public class ExOfCharacter {
 
    @FunctionalInterface
    interface Calculation {
        int go(int aaa, int bbb);
    } // end of Calculation
 
    @FunctionalInterface
    interface Message {
        void go(String message);
    } // end of Message
 
    public static void main(String args[]) {
 
        // 매개변수 유형 사용
        Calculation addition = (int nnn, int yyy) -> nnn + yyy;
        System.out.println("매개변수 유형 사용");
        System.out.println(addition.go(1,2));
 
        // 매개변수 유형 미사용
        Calculation subtraction = (kkk, hhh) -> kkk - hhh;
        System.out.println("매개변수 유형 미사용");
        System.out.println(subtraction.go(1,2));
 
        // 반환값과 중괄호 사용
        Calculation multiplication = (int lll, int ddd) -> {
            return lll * ddd;
        };
        System.out.println("반환값과 중괄호 사용");
        System.out.println(multiplication.go(1,2));
        
        // 반환값과 중괄호 미사용
        Calculation division = (int www, int fff) -> www / fff;
        System.out.println("반환값과 중괄호 미사용");
        System.out.println(division.go(1,2));
 
        // 매개변수 괄호 사용
        Message secondMessage = (message) -> System.out.println(message);
        System.out.println("매개변수 괄호 사용");
        secondMessage.go("firstMessage");
 
        // 매개변수 괄호 미사용
        Message firstMessage = message -> System.out.println(message);
        System.out.println("매개변수 괄호 미사용");
        firstMessage.go("secondMessage");
 
    } // end of main
 
// end of ExOfCharacter
cs

어떤걸 사용하면 되냐고 묻는다면, 니 맘대로 하세요.


또 다른 활용.

Excutor 포스트에서 invokeAny의 예제를 참조한다면 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package example;
 
public class ExOfHelperMethod {
 
    interface Calculation {
        int go(int aaa, int bbb);
    } // end of Calculation
    
    static Calculation getCalculation(int ccc, int ddd){
        return (aaa, bbb)->{
            return aaa + bbb + ccc + ddd;
        };
    } // end of getCalculation
 
    public static void main(String args[]) {
 
        // aaa = 3
        // bbb = 4
        // ccc = 1
        // ddd = 2
        Calculation cal = getCalculation(12);
        System.out.println(cal.go(34));
 
    } // end of main
 
// end of ExOfCharacter
cs