람다식?
람다식 또는 람다 표현식(Lambda Expression)은 프로그래밍에서 흔히 사용되는 개념으로 익명 함수 등으로 불리기도 한다. 많은 프로그래밍 언어에서 람다식을 볼 수 있으며 Java에서는 이 람다 표현식을 Java8부터 추가되어 활용할 수 있다.
특징
기본 형태
(int param1, String param2) -> { DoSomething...} // 기본
(Parameter, ...) -> { DoSomething... } // 타입이 동일한 경우
() -> { DoSomething... } // 매개변수가 없는 경우
(Parameter, ...) -> DoSomething // 단일 실행문인 경우
(Parameter, ...) -> { return some; } // 단일 실행문이 return인 경우 생략 불가
매개 변수는 위와 같은 형태로 사용한다. 매개 변수를 이용해서 중괄호 내 어떤 로직을 수행하는 것으로 해석하면 된다. 형태를 보면 알 수 있듯 이름이 없는 함수, 익명 함수(Anonymous Function)이다.
익명 함수는 다른 객체에 적용 가능한 연산을 모두 지원하는 일급 객체 특성을 가지기 때문에 함수 자체를 값으로 사용하거나 파라미터로 전달 및 변수에 대입하는 등의 연산도 가능하다.
람다식 적용 예시
public interface Calculator {
public int calculate(int num1, int num2);
}
public interface NoParamCalculator {
public void calculate();
}
public interface OneParamCalculator {
int calculate(int num);
}
여러 가지 형태의 함수가 하나만 존재하는 인터페이스, Functional Interface를 선언했다.
이 인터페이스들을 활용해서 앞에서 예시로 들었던 람다식들을 다음과 같이 구현할 수 있다.
Calculator calculator1 = (int num1, int num2) -> {
return num1 + num2;
};
System.out.println(calculator1.calculate(10, 20));
Calculator calculator2 = (num1, num2) -> {
return num1 * num2;
};
System.out.println(calculator2.calculate(10, 20));
NoParamCalculator calculator3 = () -> { System.out.println("No Param"); };
calculator3.calculate();
Calculator calculator4 = (num1, num2) -> num1 - num2;
System.out.println(calculator4.calculate(20, 10));
OneParamCalculator calculator5 = num -> num * 10;
System.out.println(calculator5.calculate(10));
사용 조건
람다식을 사용하기 위한 인터페이스에는 구현할 인터페이스의 추상 메소드가 1개여야만 한다는 조건이 있다. 2개 이상일 때를 생각해보면 당연한 제약이다. 2개 이상의 메소드는 어떤 것이 람다식으로 표현했는지 알 수 없다.
public interface NoneFunctional {
public boolean equals(Object obj); // Object 객체의 메소드만 있을 땐 Functional interface가 아님
}
public interface NoneFunctional {
public Object doSome1();
public void doSome2();
}
public interface Functional {
public boolean equals(Object obj);
public void doSome(); // 추상 메서드 하나만 있으면 Functional interface
}
public interface Functional {
public Object doSome(); // Object의 doSome은 public이 아니므로 Functional Interface
}
인터페이스의 설계자와 사용자가 다르다면, 이를 간과하고 인터페이스 설계를 변경하면서 에러가 발생하고서야 이러한 문제를 알게 되는 부분이 있다. 이럴 때는 @FunctionalInterface 어노테이션을 사용해서 이 자체를 컴파일 타임에 에러를 잡을 수 있다.
사용 예제
java.util.function 인터페이스
docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Stream API
docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
요약
장점
- 람다는 불필요한 반복문 등을 줄여서 코드를 간결하게 만들 수 있다.
- 지연 연산 수행으로 불필요한 연산을 최소화할 수도 있다.
- 멀티 스레드를 이용하면 병렬 처리도 가능하다.
단점
- 장점에서 언급한 간결한 코드가 너무 지나치면, 오히려 가독성을 해칠 수 있다.
- 호출 자체가 까다롭다.
- 람다 Stream은 단순 for, while에 비해서는 성능이 떨어진다.
'Programming Language > Java' 카테고리의 다른 글
Java의 Stream에서 parallelStream은 stream보다 항상 빠를까? (1) | 2021.07.18 |
---|---|
Java의 함수형 인터페이스(Functional Interface)에 대해 알아보기 (0) | 2021.05.17 |
자바(Java)에서의 싱글톤(Singleton) 패턴에 대해 알아보자 (1) | 2020.12.13 |
자바(Java)와 메모리(Static, Stack, Heap)에 대한 정리 (0) | 2020.10.31 |