: 사용하기 복잡한 기능이나 개념을 사용하고 싶은 사람은 아무도 없다.
: 다음 예제에서 요약하는 것처럼 현재 filterApples 메서드로 새로운 동작을 전달하려면 ApplePredicate 인터페이스를 구현하는 여러 클래스를 정의한 다음 인스턴스화해야 한다.
: 이는 상당히 번거로운 작업이면서 동시에 시간 낭비이다.
public class AppleHeavyWeightPredicate implements ApplePredicate {
public boolean test(Apple apple) {
return apple.getWeight() > 150;
}
}
public class AppleGreenColorPredicate implements ApplePredicate {
public boolean test(Apple apple) {
return GREEN.equals(apple.getColor());
}
}
public class FilteringApples {
public static void main(String...args) {
List<Apple> inventory = Arrays.asList(new Apple(80, GREEN), newApple(155, GREEN0, new Apple(120, RED));
List<Apple> heavyApples = filterApples(inventory, new AppleHeavyWeightPredicate());
List<Apple> greenApples = filterApples(inventory, new AppleGreenColortPredicate());
}
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(p.test(apple)) {
result.add(apple);
}
}
return result;
}
}
Java
복사
: 자바는 클래스의 선언과 인스턴스화를 동시에 수행할 수 있도록 익명 클래스라는 기법을 제공한다.
: 익명 클래스를 이용하면 코드의 양을 줄일 수 있다. 하지만 익명 클래스가 모든 것을 해결하는 것은 아니다.
1. 익명 클래스
: 익명 클래스는 자바의 지역 클래스와 비슷한 개념이다.
: 말 그대로 이름이 없는 클래스로, 익명 클래스를 이용하면 클래스 선언과 인스턴스화를 동시에 할 수 있다. 즉 즉석에서 필요한 구현을 생성해서 사용할 수 있다.
2. 다섯 번째 시도 : 익명 클래스 이용
: 다음은 익명 클래스를 이용해서 ApplePredicate를 구현하는 객체를 만드는 방법으로 필터링 에제를 다시 구현한 코드이다.
List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
public boolean test(Apple apple) {
return RED.equals(apple.getColor());
}
});
Java
복사
: 익명 클래스로도 아직 부족한 점이 있다.
: 첫째, 익명 클래스는 여전히 많은 공간을 차지한다.
: 둘째, 많은 프로그래머가 익명 클래스의 사용에 익숙치 않다.
3. 여섯 번째 시도 : 람다 표현식 사용
: 자바 8의 람다 표현식을 이용해서 위 예제 코드를 다음처럼 간단하게 재구현할 수 있다.
List<Apple> result = filterApples(inventory, (Apple apple) -> RED.equals(apple.getColor()));
Java
복사
4. 일곱 번째 시도 : 리스트 형식으로 추상화
: 바나나, 오렌지 등의 리스트에 필터 메서드를 사용하고 싶다면? 다음과 같이 정의할 수 있다.
public interface Predicate<T> {
boolean test(T t);
}
public static <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> result = new ArrayList<>();
for(T e : list) {
if(p.test(e)) {
result.add(e);
}
}
return result;
}
Java
복사
: 다음과 같이 사용할 수 있다.
List<Apple> redApples = filter(inventory, (Apple apple) -> RED.equals(apple.getColor()));
List<Integer> evenNumbers = filter(numbers, (Integer i) -> i % 2 == 0);
Java
복사
: 유연성과 간결함을 모두 잡을 수 있었다. 자바 8이 아니었다면 불가능했을 것이다.