[JAVA] 동적파라미터화

Jae-Baek Song·2023년 1월 14일

모던자바인액션

목록 보기
1/11
post-thumbnail

저자: 라울-게이브리얼 우르마 , 마리오 푸스코 , 앨런 마이크로프트
도서명: 모던 자바 인 액션
출판사: 한빛미디어


변화하는 요구사항에 대응하기 위한 코드로 모든 속성을 메서드 파라미터로 추가하는방법

public class AppleFilter {
    public static List<Apple> filterApples(List<Apple> inventory, Color color, int weight, boolean flag) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if ((flag && apple.getColor().equals(color)) ||
                    (!flag && apple.getWeight() > weight)) {
                result.add(apple);
            }
        }
        return result;
    }
}

Predicate 인터페이스를 활용한 방법

java.util.function.Predicate

Predicate는 제네릭 형식 T의 객체를 인자로 받고 boolean 형태의 값을 반환하는 test 메서드를 추상메서드로 가지고 있는 함수형 인터페이스 입니다.

public interface ApplePredicate {
    boolean test(Apple apple);
}

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

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

public class AppleRedAndHeavyPredicate implements ApplePredicate {
    @Override
    public boolean test(Apple apple) {
        return Color.RED.equals(apple.getColor()) && apple.getWeight() > 150;
    }
}

public class AppleFilter {
    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;
    }
}

List<Apple> redAndHeavyApples = AppleFilter.filterApples(inventory, new AppleRedAndHeavyPredicate());

복잡한 과정 간소화

익명 클래스 사용

List<Apple> redApples = AppleFilter.filterApples(inventory, new ApplePredicate() {
    @Override
    public boolean test(Apple apple) {
        return Color.RED.equals(apple.getColor());
    }
});

람다 표현식 사용

List<Apple> redApples = AppleFilter.filterApples(inventory, (Apple apple) -> Color.RED.equals(apple.getColor()));

제네릭 사용

public interface Predicate<T> {
    boolean test(T t);
}

public class Filter {
    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;
    }
}

List<Apple> filter = Filter.filter(inventory, (Apple apple) -> Color.RED.equals(apple.getColor()));

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = Filter.filter(numbers, (Integer i) -> i % 2 == 0);

실전 예제

Comparator 정렬

자바 8의 List의 sort 메서드의 파라미터인 Comparator 인터페이스를 구현하여 sort 메서드의 동작을 정할 수 있다.

public interface Comparator<T> {

  /* a negative integer, zero, or a positive integer as the
     first argument is less than, equal to, or greater than the
     second.
  */
    int compare(T o1, T o2);
}

inventory.sort(new Comparator<Apple>() {
    @Override
    public int compare(Apple o1, Apple o2) {
        return o1.getWeight() - o2.getWeight();
    }
});

inventory.sort((o1, o2) -> o1.getWeight() - o2.getWeight());

Runnable로 코드 블록 실행

스레드에 실행 할 코드 블록을 지정할 수 있다.

Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello world");
    }
});

Thread t = new Thread(() -> System.out.println("Hello world"));

0개의 댓글