프로그래밍 노트/Effective 시리즈

익명 클래스보다는 람다를 사용하라.

깡냉쓰 2019. 12. 26. 21:42
728x90
반응형

자바8에는 추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정받아 특별한 대우를 받게 되었다.
함수형 인터페이스라 부르는 이 인터페이스들의 인스턴스를 람다식(lamda expression)을 사용해 만들 수 있게 된 것이다.

Collections.sort(words, new Comparator<String>(){
        public int compare(String s1, String s2){
                return Integer.compare(s1.length, s2.length());
        }
});
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length());

컴파일러가 문맥을 살펴 타입을 추론해준다. 타입을 명시해야 코드가 더 명확할 때만 제외하고는, 람다의 모든 매개변수 타입은 생략하자.
비교자 생성 메서드를 사용하면 더 간결한 코드를 만들 수 있다.

Collections.sort(words, comparingInt(String::length));

상수별 클래스 몸체와 데이터를 사용한 열거 타입

각 상수에 apply 메서드를 재정의한 코드

@AllArgsConstructor
@ToString
public 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;
    public abstract double apply(double x, double y);
}

람다를 이용하면 쉽게 구현할 수 있다. 각 열거 타입 상수의 동작을 람다로 구현해 생성자에 넘기고, 생성자는 이 람다를 인스턴스 필드로 저장해둔다. 그런 다음 apply 메서드에서 필드에 저장된 람다를 호출하면 된다.

@AllArgsConstructor
@ToString
public enum OperationLamda {
    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;
    public double apply(double x, double y){
        return op.applyAsDouble(x, y);
    }
}

람다는 이름이 없고 문서화도 못 한다. 따라서 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다.

728x90
반응형