자바8 - 람다 표현식

현시기얌·2021년 8월 10일
0

JAVA8

목록 보기
3/8

람다

(인자 리스트) -> {바디}

인자리스트

  • 인자가 없을 때 : ()
  • 인자가 한개일 때 : (one) 또는 one
  • 인자가 여러개 일 때 : (one,two)
  • 인자 타입은 생략 가능, 컴파일러가 추론하지만 명시할 수도 있다. (Integer one, Integer two)

바디

  • 화살표 오른쪾에 함수 본문을 정의한다.
  • 여러 줄인 경우에 {}를 사용해서 묶는다.
  • 한 줄인 경우에 생략 가능, return도 생략 가능

변수 캡쳐(Variable Capture)

public class LambdaExample {

public static void main(String[] args) {
    LambdaExample lambda = new LambdaExample();
    lambda.run();
}

private void run() {
    //local Variable
    int baseNumber = 100;

    //로컬 클래스
    class LocalClass {
        void printBaseNumber() {
            System.out.println(baseNumber);
        }
    }

    // 익명 클래스
    Consumer<Integer> integerConsumer = new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) {
            System.out.println(baseNumber);
        }
    };

    // 람다
    IntConsumer printInt = (i) -> System.out.println(i + baseNumber);

    printInt.accept(100);
}

}

  • 로컬 변수 캡처

    • final이거나 effective final인 경우에만 참조할 수 있다.
    • 그렇지 않을 경우 concurrency 문제가 생길 수 있어서 컴파일러가 방지한다.
  • effective final

    • 이것도 역시 자바8부터 지원하는 기능으로 사실상 final 변수
    • fianl 키워드 사용하지 않은 변수를 익명 클래스 구현체 또는 람다에서 참조할 수 있다.
  • 익명 클래스 구현체와 달리 쉐도윙하지 않는다.

    • 익명 클래스는 새로 스콥을 만들지만, 람다는 람다를 감싸고 있는 스콥과 같다.

로컬 클래스, 익명 클래스 VS 람다 차이점

람다는 쉐도잉을 하지 않는다!!

  public class Name{
        private String name;
    }
  • 람다의 스콥은 람다를 감싸고 있는 메소드와 같다.

로컬 클래스나 익명 클래스는 외부의 지역 변수의 이름과 같은 지역변수가 내부에 생겼을 경우 내부에 있는 값으로 쉐도윙이 된다.

   
   private void run() {
        //local Variable
        int baseNumber = 100;

        //로컬 클래스
        class LocalClass {
            void printBaseNumber() {
                int baseNumber = 11;
                System.out.println(baseNumber);
            }
        }

        // 익명 클래스
        Consumer<Integer> integerConsumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer baseNumber) {
                System.out.println(baseNumber);
            }
        }

따라서 위의 코드에서 로컬 클래스의 baseNumber의 값은 11이 되고
익명 클래스의 baseNumber의 값은 accept 메소드 변수에 할당된 값이 된다.

   private void run() {
      //local Variable
      int baseNumber = 100;
      // 람다
      
      // 불가능 
      IntConsumer printInt = (baseNumber) -> System.out.println(baseNumber + baseNumber); 
      
      // 가능
      IntConsumer printInt = (i) -> System.out.println(i + baseNumber); 

   
      printInt.accept(100);
      
     
  }

하지만 람다는 run() 함수와 같은 스콥이기 때문에 동일한 이름의 변수를 정의할 수 없다.

  private void run() {
     //local Variable
     int baseNumber = 100;
     // 람다
     
     // 불가능 
     IntConsumer printInt = (baseNumber) -> System.out.println(baseNumber + baseNumber); 
     
     // 불가능
     IntConsumer printInt = (i) -> System.out.println(i + baseNumber); 

  
     printInt.accept(100);
     
     baseNumber++;
 }

또한 위와 같이 지역 변수의 값이 effective final이 아닐때에도 람다에서 지역 변수를 사용할 수 없다.

profile
현시깁니다

0개의 댓글

관련 채용 정보