2023. 12. 18. 21:20ㆍBook/이펙티브 자바
옛날에는 추상 메소드가 하나인 인터페이스 변수에 익명클래스를 대입했다.
public static void main(String[] args) {
List<String> stringList = List.of("he", "llo", "wor", "ld");
Collections.sort(stringList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
}
자바 8에 와서 추상 메서드 하나짜리 인터페이스는 함수적 인터페이스라고 불리는데, 이 인터페이스들의 인스턴스를 람다식을 사용해 만들 수 있게 됐다.
Collections.sort(stringList,
(o1, o2) -> Integer.compare(o1.length(), o2.length()));
여기서 람다, 매개변수(s1, s2), 반환값의 타입은 각각 (Comparator<String>), String, int이고 컴파일러가 타입을 추론한다.
만약 컴파일러가 타입을 추론하지 못한다면 프로그래머가 직접 명시해주면 된다.
타입을 명시해야 코드가 더 명확할 때만 제외하고는, 람다의 모든 매개변수 타입은 생략하자.
람다 자리에 비교자 생성 메서드를 사용하면 이 코드를 더 간결하게 만들 수 있다.
Collections.sort(stringList, Comparator.comparingInt(String::length));
더 나아가 자바 8 때 List 인터페이스에 추가된 sort 메서드를 이용하면 더욱 짧아진다.
stringList.sort(Comparator.comparingInt(String::length));
람다를 언어 차원에서 지원하면서 기존에는 적합하지 않았던 곳에서도 함수 객체를 실용적으로 사용할 수 있게 됐다.
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;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
public abstract double apply(double x, double y);
}
아이템 34에서 상수별 클래스 몸체를 구현하는 방식보다는 열거 타입에 인스턴스 필드를 두는 편이 낫다고 했다. 람다를 이용하면 후자의 방식, 즉 열거 타입의 인스턴스 필드를 이용하는 방식으로 상수별로 다르게 동작하는 코드를 쉽게 구현할 수 있다.
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 는 바깥 인스턴스
'Book > 이펙티브 자바' 카테고리의 다른 글
Item45 - 스트림은 주의해서 사용하라 (0) | 2023.12.21 |
---|---|
Item43 - 람다보다는 메서드 참조를 사용하라 (0) | 2023.12.19 |
Item41 - 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2023.12.17 |
Item40 - @Override 애너테이션을 일관되게 사용하라 (0) | 2023.12.17 |
Item39 - 명명 패턴보다 애너테이션을 사용하라 (1) | 2023.12.17 |