Lambda Expression(람다식)
- 익명클래스에서 이름을 지정하지 않고 기본 클래스를 구현했다. 하지만 메소드가 하나뿐인 클래스의 경우 익명클래스도 코드가 간결하지 않고 복잡해보인다. 그래서 나온게 람다식이다.
- 람다식은 하나의 메소드만 있는 클래스의 인스턴스를 익명클래스 보다 더 간결하게 표현할 수 있다.
Functional Interfaces(함수형 인터페이스)
- 오직 하나의 추상메소드만 올 수 있으며 default, static 메소드는 정의에 영향이 가지 않으며 하나 이상 올 수 있다.
- 람다식은 Functional Interfaces(함수형 인터페이스)를 기반으로만 사용할 수 있다.
- 함수형 인터페이스는 @FunctionalInterface 어노테이션을 사용할 수 있으며 사용을 권장한다.
@FunctionalInterface 어노테이션은 인터페이스의 목적을 명확하게 전달할 뿐만 아니라 함수형 인터페이스의 조건을 충족하지 않는 경우 컴파일러가 에러를 발생시킨다.
즉, 아래와 같이 사용할 수 있다.
@FunctionalInterface
interface FunctionalInterfaces<T> {
T test(T t);
void test2(); // 이 코드가 삽입되면 @FunctionalInterface 에 의해 컴파일 에러 발생
}
다음은 정렬 인터페이스를 구현하는 람다식을 사용하지 않은 코드이다.
@FunctionalInterface
interface Sort<T> {
boolean sort(T t1, T t2);
default void swap(List<T> list, int a, int b) {
T x = list.get(a);
list.set(a, list.get(b));
list.set(b, x);
}
}
class FunctionalSort implements Sort<Integer> {
@Override
public boolean sort(Integer t1, Integer t2) {
return t1 > t2;
}
}
class TestMain {
public static void sortFunc(List<Integer> list, Sort<Integer> sort) {
for (int i = 0; i < list.size() - 1; i++)
for (int j = i; j >= 0 && sort.sort(list.get(j), list.get(j + 1)); j--)
sort.swap(list, j, j + 1);
System.out.print(list);
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 10, 4, 11, 2, 7, 15, 8);
sortFunc(list, new FunctionalSort());
}
}
sort 함수를 사용하기 위해 Sort 인터페이스를 구현하는 클래스를 만들어 인스턴스를 생성해 전달하는 것을 볼 수 있다.
이는 하나의 기능을 사용하기 위해서 작성되는 불필요한 상용구 코드가 많다는 것을 느낄 수 있다.
다음은 람다식을 사용하는 코드이다.
@FunctionalInterface
interface Sort<T> {
boolean sort(T t1, T t2);
default void swap(List<T> list, int a, int b) {
T x = list.get(a);
list.set(a, list.get(b));
list.set(b, x);
}
}
class TestMain {
public static void sortFunc(List<Integer> list, Sort<Integer> sort) {
for (int i = 0; i < list.size() - 1; i++)
for (int j = i; j >= 0 && sort.sort(list.get(j), list.get(j + 1)); j--)
sort.swap(list, j, j + 1);
System.out.print(list);
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 10, 4, 11, 2, 7, 15, 8);
sortFunc(list, (a, b) -> a > b); // 람다식 사용
}
}
FunctioanlSort 클래스를 없애고 (a, b) -> a > b 한 문장으로 클래스를 대신하는 것을 볼 수 있다.
익명 클래스로부터 람다식까지 변환 과정
- 컴파일러는 sortFunc의 두 번째 매개변수가 Sort <Integer> sort 참조형이므로 인자로 이를 구현하는 인스턴스의 생성문이 올 수 있다는 것을 유추할 수 있다. 따라서 new Sort<Integer>()는 생략이 가능하다.
- Sort<Integer> 인터페이스의 추상메소드는 boolean sort(Integer t1, Interger t2) 이므로 이 메소드를 구현한다고 유추할 수 있다. 따라서 public boolean sort는 생략이 가능하다.
- 추상메소드 sort의 매개변수형 또한 유추가 가능하므로 Interger를 생략할 수 있다.
- return문을 생략하면 알아서 반환의 대상으로 인식한다.
'Programming > JAVA' 카테고리의 다른 글
Effectively final (0) | 2020.12.11 |
---|---|
Nested Class, Inner Class (0) | 2020.12.08 |
Set<E> (0) | 2020.12.02 |
댓글