Lambda Expressions 기본식 (1)

람다식 (Lambda Expressions)


람다식 (Lambda Expressions) 이란?

  • 수학자 알론조(Alonzo Church)가 발표한 람다 계산법에서 사용된 식으로, 이를 제자 존 매카시(John Macarthy)가 프로그래밍 언어에 도입

  • Java8 버전부터 이 람다식(Lambda Expressions)을 지원

  • 람다식은 익명함수(Anonymous Function)을 생성하기 위한 식으로 객체 지향 언어보다 함수 지향 언어에 가까움

  • 람다 형태는 매개변수를 가진 코드 블록이지만, 런타임 시에는 익명 구현 객체(추상메소드를 한 개 포함한)를 생성

  • 출처 : https://juyoung-1008.tistory.com/48

람다식의 장점

  • 코드의 간결성

    • 효율적인 람다 함수의 사용을 통하여 불필요한 루프문의 삭제가 가능하며, 동일한 함수를 재활용할 수 있는 여지가 커진다.
  • 필요한 정보만을 사용하는 방식을 통한 퍼포먼스 향상

    • 지연 연산을 지원하는 방식을 통하여 효율적인 퍼포먼스를 기대할 수 있다.

    • 이 경우 메모리상의 효율성 및 불필요한 연산의 배제가 가능하다는 장점이 있다.

람다식의 단점

  • 어떤 방법으로 작성해도 모든 원소를 전부 순회하는 경우는 람다식이 조금 느릴 수 밖에 없다.(어떤 방법으로 만들어도 최종 출력되는 bytecode나 어셈블리 코드는 단순 반복문보다 몇 단계를 더 거치게 된다.)

  • 익명함수의 특성상 함수 외부의 캡처를 위해 캡처를 하는 시간제약, 논리제약적인 요소도 고려해야 하며, 디버깅 시 함수 콜스택 추적이 극도로 어렵다.

  • 람다식을 남용하면 오히려 코드를 이해하기 어려울 수 있다.

람다식 기본 문법

@FunctionalInterface

  • 단 하나의 public method만 가지고 있는 interface
  • annotation 생략 가능
  • Lambda 사용 시, 반드시 @FunctionalInterface여야 한다.
  • java.util.function package 참조

기본 문법

  • () -> code
    • 명령이 한 줄인 경우 {}, return 생략 가능
  • (paramter) -> code;
    • 파라미터가 한 개인 경우 () 생략 가능
  • (param1, param2) -> code;
  • (parameter...) -> {codes;}
    • 파라미터 타입 생략 가능 (타입 추론)

메소드 참조

  • 이름이 있는 메소드에 대한 간단한 호출 형태
  • 메서드를 메서드의 파라미터로 전달하여 사용
  • 축약된 표현식 -> 간결한 코드 (코드를 이해하기 힘들 수 있음)

간단한 Lambda Expressions 문법

Test01.java

01 package com.test01;
02
03 // @FunctionalInterface : method가 하나인 인터페이스
04 @FunctionalInterface
05 public interface Test01 {
06
07     public void prn();
08 
09 }

MTest.java

01 package com.test01;
02
03 public class MTest {
04 /*
05   기존방식
06   class inner implements Test01 {
07
08       @Override
09      public void prn() {
10
11
12
13  */    
14     public static void main(String[] args) {
15         Test test01_1 = new Test01() {
16             @Override
17             public void prn() {
18                 System.out.println("Interface 구현!");
19             }
20         };
21         test01_1.prn();
22
23         // () -> {code};
24         Test01 test01_2 = () -> {System.out.println("Lamda!");};
25         test01_2.prn();
26         // FunctionalInterface만이 람다식으로 변환할 수 있다. 왜냐하면 메소드가 하나이기 때문이다
27
28         // () -> code;
29         Test01 test01_3 = () -> System.out.println("Lambda! 재밌다!");
30         test01_3.prn();
------
Interface 구현!
Lamda!
Lambda! 재밌다!

Test02.java

01 packge com.test01;
02
03 public interface Test02 {
04     void prn(int i);
05 }

MTest.java

34     // (parameter) -> {};
35     Test02 test02_1 = (int i) -> {System.out.println("input : " + i);};
36     test02_1.prn(10);
37     
38     Test02 test02_2 = (i) -> {System.out.println("input : " + i);};
39     test02_2.prn(20);
40
41     // parameter -> {};
42     Test02 test02_3 = i -> System.out.println("input : " + i);
43     test02_3.prn(30);
------
input : 10
input : 20
input : 30

Test03.java

01 package com.test01;
02
03 // @FunctionalInterface
04 public interface Test03 {
05
06     public int prn(int i);
07 }

MTest.java

47     // parameter -> {return };
48     Test03 test03_1 = i -> {return i + 10;};
49     System.out.println(test03_1.prn(10));
50
51     // parameter -> code; // return 생략
52     Test03 test03_2 = i -> i + 20;
53     System.out.println(test03_2.prn(10));
------
20
30

Test04.java

01 package com.test01;
02
03 public interface Test04 {
04
05     public int prn(int i, int j);
06
07 }

MTest.java

57     // (param1, param2) -> {return code;};
58     Test04 test04_1 = (n, m) -> {return n + m;};
59     System.out.println(test04_1.prn(10, 20);
60
61     // (param1, param2) -> code;
62     Test04 test04_2 = (n, m) -> n * m;
63     System.out.println(test04_2.prn(10, 20);
64
65     // (param1, param2) -> {code; return code;};
66     Test04 test04_3 = (n, m) -> {
67         System.out.printf("%d * %d = ", n, m);
68         return n * m;
69     };
70     System.out.println(test04_3.prn(30, 40));
71     }
72 
73 }
------
30

좋은 웹페이지 즐겨찾기