[코드 42-1] 익명 클래스의 인스턴스를 함수 객체로 사용한 예시
Collectorions.sort(words, new Comparator<String>(){
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
과거 객체 지향 디자인 패턴에서는 익명 클래스면 충분했지만,
코드가 너무 길기 때문에 함수형 인터페이스에는 적절하지 않았다.
자바8에서부터 함수형 인터페이스(추상 메서드 하나를 갖는 인터페이스)를 사용할 수 있게 되었다.
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length())); // 람다
코드가 훨씬 간결해졌다.
매개변수 (s1, s2)의 반환값은 (Comparator<String>), String, int지만 코드에서는 언급이 없다.
컴파일러가 문맥을 살펴서 타입을 추론해주기 때문인데, 추론 규칙은 굉장히 복잡해서 다 이해하는 프로그래머도 거의 없다.
타입을 명시해야 코드가 더 명확할 때(=컴파일러에서 '타입을 알 수 없다'는 오류를 낼 때) 말고는 람다의 모든 매개변수 타입을 생략하면 된다.
여기서 코드를 더 줄이면, 자바8에서 추가된 List 인터페이스의 sort 메서드와 비교자 생성 메서드를 사용하면 된다.
Collections.sort(words, comparingInt(String::length));
아이템34의 Operation 열거타입을 예로 보자.
public enum Operation {
PLUS("+", (x,y) -> x+y),
MINUS("-", (x,y) -> x-y),
TIMES("*", (x,y) -> x*y),
DIVIDE("/", (x,y) -> x/y);
... 생략
}
로 apply 추상메서드 구현부를 람다로 표현할 수 있다.
대신 람다는 1-3줄이여야 적당하다. 그 이상으로 길어지면 가독성이 나빠지기 때문에, 반대로 람다를 제거하는 것으로 리팩터링 하는 것이 좋다!
또한 람다의 this는 자기자신이 아닌 바깥 인스턴스를 가리키기 때문에 주의해야 한다.
'Java' 카테고리의 다른 글
[Effectiva Java][아이템41] 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (마커 인터페이스, 마커 애너테이션의 적절한 쓰임) (0) | 2022.07.04 |
---|---|
[Effectiva Java][아이템40] @Override 애너테이션을 일관되게 사용하라 (0) | 2022.07.04 |
[Effectiva Java][아이템37] ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.06.18 |
[Effective Java][아이템36] 열거정수를 집합으로 사용해야 하는 경우 - EnumSet (0) | 2022.06.18 |
[Effective Java][아이템35] ordinal 메서드를 잘못사용한 사례와 해결방법 (0) | 2022.06.12 |