티스토리 뷰

반응형

예전 자바에서는 함수 객체를 만드는 주요 수단은 익명 클래스였다.

함수 객체 : 추상 메서드를 하나만 담은 인터페이스의 인스턴스

//익명 클래스의 인스턴스를 함수 객체로 사용 - 낡은 기법 
Collections.sort(words, new Comparator<String>() {
      @Override
      public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
      }
});

 

람다식

자바8부터 추상 메서드 하나만 담은 함수형 인터페이스의 인스턴스를 람다식을 이용해 만들 수 있게 되었다.

람다는 함수나 익명 클래스와 개념은 비슷 but 코드는 더 간결하고 명확함

//람다식을 함수 객체로 사용 - 익명 클래스 대체 
Collections.sort(words,(s1,s2)->Integer.compare(s1.length(),s2.length()));

매개변수(s1,s2)와 반환값의 타입이 코드에 나타나있지 않다.

컴파일러가 대신 타입을 추론해준다.

상황에 따라 컴파일러가 타입을 결정하지 못할때만 명시해주면 된다.

컴파일러가 타입 추론시에 타입 정보를 제네릭에서 얻어온다. → 로 타입이 아닌 매개변수화 타입 사용하자.

 

 

열거 타입에서 람다식 사용하기

상수마다 메서드 동작을 다르게 해야하는 경우에 상수별 메서드 구현을 했었다. [아이템34]

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; }};

        public abstract double apply(double x, double y);

        private final String symbol;

        Operation(String symbol) { this.symbol = symbol; }

        @Override public String toString() { return symbol; }
}

위 코드에서 상수별 클래스 몸체를 구현하는 방식보다 열거 타입에 인스턴스 필드를 두는 편이 낫다.

람다를 이용하여 인스턴스 필드로 상수별로 다르게 동작하게 할 수 있다.

//람다를 인스턴스 필드에 저장해 상수별 동작을 구현한 열거 타입 - 간결하고 깔끔 
public 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);
    }
}

 

 

람다와 익명 클래스

  • 람다는 이름이 없고 문서화도 못하므로 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다.
  • 람다는 한줄에서 세줄안에 끝내는게 좋다.
  • 함수형 인터페이스(추상 메서드가 하나인)에서만 쓰임 (추상 클래스의 인스턴스를 만들때는 익명 클래스 써야함)
  • 추상 메서드가 여러개인 인터페이스의 인스턴스를 만들때도 익명 클래스를 쓸 수 있음
  • 람다는 자신을 참조할 수 없음 (람다에서의 this 는 바깥 인스턴스를 가리킴) → 자신을 참조해야한다면 무조건 익명 클래스 사용하라.
  • 람다와 익명 클래스 모두 직렬화가 구현별로 다를 수 있으므로 직렬화를 삼가고 private 정적 중첩 클래스의 인스턴스[아이템24]를 사용하라.

 

결론

익명 클래스는 함수형 인터페이스가 아닌 타입의 인스턴스를 만들때만 사용하고 그 외에는 람다를 사용하라.

람다는 간결하고 쉽게 표현할 수 있어 자바의 함수형 프로그래밍의 지평을 열었다.

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday