본문 바로가기

Java/Java8

(JAVA8) 람다식으로 향하는 과정

1. 녹색 사과 필터링

리스트를 돌면서 green  인 color가 있으면 리스트에 저장해서 리턴한다.

public class Exercise {
    public static void main(String[] args) {
        List<Apple> inventory = Arrays.asList(new Apple(80,"green"), new Apple(20,"red"));
        List<Apple> apples = filterGreenApples(inventory);
        System.out.println(apples.get(0).getColor());

    }
    /*초록색을 필터링*/
    public static List<Apple> filterGreenApples (List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for(Apple apple : inventory) {
            if("green".equals(apple.getColor())) {
                result.add(apple);
            }
        }
        return result;
    }
}

2. 색을 파라미터화

파라미터에  color를 추가하여 클라이언트에서 원하는 파라미터를 전송할 수 있게 설정

public class Exercise {
    public static void main(String[] args) {
        List<Apple> inventory = Arrays.asList(new Apple(80,"green"), new Apple(20,"red"));
        List<Apple> apples = filterGreenApples(inventory, "green");
        System.out.println(apples.get(0).getColor());

    }
    /*초록색을 필터링*/
    public static List<Apple> filterGreenApples (List<Apple> inventory, String color) {
        List<Apple> result = new ArrayList<>();
        for(Apple apple : inventory) {
            if(apple.getColor().equals(color)) {
                result.add(apple);
            }
        }
        return result;
    }
}

 

만약 여기에 무게에 대한 필터링을 추가하게 된다면 코드의 중복이 발생한다. - DRY 원칙 위배

 

3. 가능한 모든 속성으로 필터링

사과의 색깔을 고를 땐 true 사과의 무게를 고를 땐 false

public static List<Apple> fiilterApples(List<Apple> inventory, String color, int weight, boolean flag) {

    List<Apple> appleList = new ArrayList<>();

    for(Apple apple : inventory) {
        if(flag && apple.getColor().equals(color) || !flag && apple.getWeitght() > weight) {
            appleList.add(apple);
        }
    }

    return appleList;
}

이건 정말 말이 안 되는 코드다.

만약 조건이 바뀐다면 코드 자체를 수정해야 하고 무수히 많은 경우의 수에 대해서 대처하는 것이 불가능하다.

또한 "사과의 색깔을 고를 땐 true 사과의 무게를 고를 땐 false" 해당 전제조건에 대해서 잘 알고 있어야 사용이 가능하다.

 

4. 동작 파라미터화 : 프레디 케이트의 사용

프레디 케이트 : 선택 조건의 결정하는 인터페이스

 

무게를 비교하는 전략

public class AppleHeavyWeightPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple apple) {
        return apple.getWeitght() < 150;
    }
}

색깔을 비교하는 전략

public class AppleGreenColorPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple apple) {
        return apple.getColor().equals("green");
    }
}

 

filterApple의 파라미터로 프레 디케이터를 설정해서 런타임 시점에 해당 프레 디케이터가 결정 나도록 설계

public class Exercise {
    public static void main(String[] args) {
        List<Apple> appleList = Arrays.asList(new Apple(60, "green"), new Apple(100, "red"));
        List<Apple> result = filterApple(appleList, new AppleGreenColorPredicate());
        System.out.println(result.isEmpty());

    }

    public static List<Apple> filterApple(List<Apple> inventory, ApplePredicate applePredicate) {
        List<Apple> appleList = new ArrayList<>();
        for(Apple apple : inventory) {
            if (applePredicate.test(apple)) {
                appleList.add(apple);
            }
        }
        return appleList;
    }

}

여기서 아쉬운 점은 test 메서드를 프레디 케이트 객체로 감싸서 전달해야 하는 것이다.

 

5. 익명 클래스의 사용

인터페이스 인스턴스 생성 후 내부에 있는 미구현 메서드를 따로 빼지 않고 직접 구현

ApplePredicate applePredicate = new ApplePredicate() {
	
	@Override
	public List<Apple> calculate(List<Apple> inventory) {
		// TODO Auto-generated method stub
		for(Apple apple : inventory) {
			if(apple.getColor().equals("red")) {
				result.add(apple);
			}
		}	
		return result;
	}
};

6. 람다식의 사용

시그니쳐 변경

@FunctionalInterface
public interface ApplePredicate {
	void calculate(List<Apple> inventory);
}

인터페이스 안에 정의돼있는 calculate를 선언하지 않고 람다식 이용해여 직접 호출한다.

이때 자세히 볼 것은 시그니처에 정의되어있는 파라미터 타입을 정의하지 않고 파라미터 명만 선언하고 body로 던지는 점이다.

ApplePredicate applePredicate = (inventory2) -> {			
	for(Apple apple : inventory2) {
		if(apple.getColor().equals("red")) {
			result.add(apple);
		}
	}
};

'Java > Java8' 카테고리의 다른 글

(JAVA8) 스트림의 활용 (2)  (0) 2020.01.19
(JAVA8) 람다식 (2)  (0) 2020.01.19
(JAVA8) 스트림의 개요 (1)  (0) 2020.01.03
(JAVA8) 람다식 (1)  (0) 2020.01.03
(JAVA8) Java8 개요  (0) 2019.11.11