[Java] Lambda에 대해서
람다 표현식은 다음과 같이 사용 된다.
(인자, 인자 .. ) => {Body}
인자
- 인자가 없을 때에는 ()사용
- 인자가 한개일 때에는 (o1) or o1
- 인자가 여러개 일 때에는 (o1, o2 …)
- 인자의 타입은 생략가능하지만 명시할 수도 있다.
Body
- 화살표 오른쪽에 함수 본문을 정의
- 함수 본문이 여러 줄을 내포한 경우 {}로 감싸기
- 한줄인 경우에는 생략가능
예시코드는 다음과 같습니다.
/*
인자가 없는 경우
*/
Supplier<Integer> getYear = () -> LocalDate.now().getYear();
System.out.println("getYear = " + getYear.get());
/*
인자가 한개인 경우
*/
Function<Integer, Integer> add10 = n -> n + 10;
System.out.println("add10(3) = " + add10.apply(3));
/*
인자가 두개 이상인 경우
*/
BinaryOperator<Integer> addCalculator = (n1, n2) -> n1 + n2;
System.out.println("addCalculator(3,10) = " + addCalculator.apply(3, 10));
변수 캡처 (Variable Capture)
- 로컬 변수 캡처
- final 혹은 effective final 변수인 경우에만 참조할 수있다.
- effective final
- final 키워드를 적지는 않았지만 사실상 변수인 것을 effective final 이라고 한다.
- Local class 혹은 익명클래스의 경우 ‘Shawdoing’이 가능하다.
- Lambda의 경우 Shawdoing을 하지 않는다.
예시 코드는 다음과 같습니다.
private void Capture() {
int localVariable = 10;
/*
Local Class
*/
class LocalClass {
int localVariable = 20;
void printNumber() {
System.out.println("Value of LocalClass = " + localVariable);
}
}
/*
익명 클래스
*/
Consumer<Integer> integerConsumer = new Consumer<>() {
@Override
public void accept(Integer localVariable) {
System.out.println(localVariable);
}
};
/*
Lambda
*/
IntConsumer lambda = (i) -> {
// int localVariable = 12; // reuse previous variable
System.out.println(i + localVariable);
};
LocalClass localClass = new LocalClass();
localClass.printNumber();
integerConsumer.accept(13);
lambda.accept(10);
}
[실행 결과]
Value of LocalClass = 20
13
20
예시코드에서 Capture라는 mehtod안에 지역변수로 localVariable
이 할당 되어 있다.
LocalClass 및 익명 클래스의 경우 똑같은 변수명으로 localVariable
을 사용할 경우 기존 값인 10 이 묻히며 다른 값으로 변경이 됩니다. 하지만 Lambda의 경우 똑같은 변수명으로 재정의 하려고 하면 reuse previous variable
컴파일 에러가 발생합니다.
댓글남기기