Java - 5. 람다식

갓김치·2020년 9월 21일
0

고급자바

목록 보기
12/47
post-custom-banner

참고

람다식?

  • 익명함수를 생성하기 위한 식
  • 자바에서는 '매개변수를 가진 코드 블럭'
    • 런타임시 익명구현 객체로 생성됨

특징

  • 람다식으로 변환할 수 있는 인터페이스: 추상메서드가 1개인 인터페이스
    • 함수적 인터페이스(@FunctionalInterface)만 가능

형식

사용시

인터페이스명 객체변수명 = 람다식;

람다식 형식

(매개변수들...) -> {처리할 코드들;...}

예시 - T01_LambdaTest

main()내

// 람다식을 사용하지 않는 경우
Thread th1 = new Thread ( // Runnable 객체를 매개변수로 받는 Thread생성자
  new Runnable() { // Runnable 인터페이스 구현

    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
        System.out.println(i);
      }
    }
  }
);
th1.start();

// 람다식을 사용하는 경우
Thread th2 = new Thread(
  (/*void*/) -> { // {} 메서드 몸체
    for (int i = 0; i < 10; i++) {
      System.out.println("람다 - " + i);
    }		
  }
);
th2.start();

람다식 작성 방법

  • 기본형식: (자료형이름 매개변수명, ...) -> { 실행문들; ... }
// 1. 매개변수 '자료형이름' 생략가능
(int a) -> { System.out.println(a); }
(a)  -> { System.out.println(a); }

// 2. 매개변수가 1개일 때: 괄호'()' 생략 가능
// (단, '자료형이름'을 지정할 경우 생략불가)
a -> { System.out.println(a); }

// 3. 실행문 1개일 때: { } 생략가능
// (문장의 끝을 나타내는 세미콜론(;)도 생략)
a -> System.out.println(a)

// 4. 매개변수가 하나도 없어도 '( )' 생략 불가
() -> System.out.println(a)

// 5. 반환값 있을 때: return 사용
(a, b) -> { return a+b; }

// 6. 실행문에 return문만 있을 때:
//    return명령과 '{ }'를 생략 가능
(a, b) -> return a + b;
(a, b) -> a + b

예시 - T02_LambdaTest.java

1단계: LambdaTestInterface.java

  • 함수적 인터페이스 => 추상메서드가 1개만 선언된 인터페이스
@FunctionalInterface
public interface LambdaTestInterface1 {
  // 반환값X 매개변수x 추상메서드
  public void test();
}

@FunctionalInterface
interface LambdaTestInterface2 {
  // 반환값X 매개변수O 추상메서드
  public void test(int a);
}

@FunctionalInterface
interface LambdaTestInterface3 {
  // 반환값O 매개변수O 추상메서드
  public int test(int a, int b);
}

2단계: 람다식 사용, 비사용 비교

  • main() 내
// 람다식을 사용하지 않았을 경우
// 구현체클래스 따로 없이 익명객체 생성 -> 매번 추상 메서드를 정의해줘야함
LambdaTestInterface1 lam1 = new LambdaTestInterface1() {

  @Override
    public void test() {
      System.out.println("익명객체 구현 방식");
    }
};
lam1.test(); // 메서드 호출

// 람다식 사용
lambdaTestInterface1 lam2 = () -> System.out.println("람다식짱!");
lam2.test(); // 메서드 호출

3단계: 작성방법에 따른 생략정도 비교

// LambdaTestInterface2 ======
// 생략 없을 때
LambdaTestInterface2 lam3 =
  (int z) -> {
    int result = z + 100;
    System.out.println(result);
  };
lam3.test(30); // 출력: 130

// 매개변수: 자료형 생략, 1개여서 괄호 생략
LambdaTestInterface2 lam4 =
  z -> {
    int result = z + 300;
    System.out.println(result);
  };
lam4.test(60); // 360

// 매개변수: 자료형 생략, 1개여서 괄호 생략
// 실행문: 1문장이여서 { } 생략
LambdaTestInterface2 lam5 =
	z -> System.out.println(z + 500);
lam5.test(90); // 590


// LambdaTestInterface3 ======
// 생략없을 때
LambdaTestInterface3 lam6 =
  (int x, int y) -> {
    int r = x + y;
    return r;
  };
int k = lam6.test(20,50); // k = 70

// 매개변수: 자료형 생략
LambdaTestInterface3 lam7 =
  x, y -> {
      return x + y ;
  };
k = lam7.test(80, 50); // k = 130

// 매개변수: 자료형 생략
// 실행문: return문만 있을 경우, return과 { } 생략 가능
LambdaTestInterface3 lam8 =
	(x, y) -> x + y; // 세미콜론도 생략가능하나, 컴파일러가 헷갈려하니까 붙여줌
k = lam8.test(100, 200); // k = 300

// 삼항조건식같은 경우는 return문만 있어도 생략하지 않는다.
LambdaTestInterface3 lam9 = 
  (x ,y) -> { return x > y ? x : y; };
k = lam9.test(100, 200); // 200

람다식의 지역변수

  • 람다식 내부에서 사용되는 지역변수는 모두 final이어야 한다.
  • 보통은 final을 붙이지 않으면 컴파일러가 자동으로 붙여준다.
  • 단, 지역변수의 값을 변경하는 식이 있을 경우에는 자동으로 final을 붙여주지 않는다.

예시 - T03_LambdaTest

public class T03_LambdaTest {
static int stVar = 9;
private String name = "홍길동";

  public void testMethod(final int temp) {
    final int localVar = 50;
    int kor = 100;

    //temp = 500;
    //localVar = 2000;
    kor = 400; // 주석처리한다면 effectively final

    // 람다식에서 지역변수 사용하기
    LambdaTestInterface1 lt = 
      () -> {
        System.out.println("temp = " + temp); // 200
        System.out.println("localVar = " + localVar); // 50
        //System.out.println("kor = " + kor); // final을 붙이던, 안에서 값을 바꾸지말아라..
        System.out.println("stVar = " + stVar); // 9
        System.out.println("name = " + this.name); // 홍길동
      };
    lt.test(); // 실행
  } // testMethod

  public static void main(String[] args) {
    new T03_LambdaTest().testMethod(200);
  }

} // class
profile
갈 길이 멀다
post-custom-banner

0개의 댓글