익명 클래스를 함수 객체로 사용하는 것은 낡은 방식이다
•
자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스나 추상클래스를 사용했다. 이렇게 추상 메서드 하나만 담고 있는 인터페이스나 추상클래스를 함수 객체(function object)라 부르고, 특정 함수나 동작을 나타내는데 사용한다.
•
이전에는 아래와 같이 함수 객체를 만들 때, 익명 클래스를 사용했다.
Collection.sort(words, new Comparator<String>() {
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
Java
복사
•
하지만 이런 익명 클래스를 사용하는 방식은 코드가 너무 길어, 함수형 프로그래밍에 적합하지 않다.
•
자바 8부터는 추상 메서드가 하나만 포함된 인터페이스를 함수형 인터페이스라 부르는데, 함수형 인터페이스를 람다식(lambda expression)을 사용해 만들 수 있게 되었다.
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length());
Java
복사
•
이처럼 람다식을 사용하면 코드를 훨씬 짧고 간결하게 표현할 수 있다.
•
람다식에서는 컴파일러가 타입을 추론하여 결정하는데, 컴파일러가 타입을 결정하지 못하는 경우에는 직접 명시해야한다.
•
타입을 명시해야 코드가 더 명확해질 때를 제외하곤, 람다의 모든 매개변수 타입은 생략하자.
Comparator 람다식으로 축약하기
람다식으로 코드를 더 간결하게 표현하기
•
위의 코드에서 비교자 생성 메서드와 메서드 참조를 사용하면 더 간결하게 만들 수 있다.
Collections.sort(words, comparingInt(String::length));
Java
복사
•
더 나아가 자바 8의 List에 추가된 sort 메서드를 이용하면 더 줄일 수 있다.
words.sort(comparingInt(String::length));
Java
복사
•
이전 장의 열거형 타입에서도 유용하게 사용할 수 있다.
enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x * y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
public abstract double apply(double x, double y);
}
Java
복사
enum Operation {
PLUS("+", (x, y) -> x + y),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override
public String toString() { return symbol; }
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
Java
복사
람다식의 단점
•
람다는 이름이 없고 문서화를 할 수 없다.
•
코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야한다.
•
람다식을 직렬화하는 것을 극히 삼가야 한다.