BiPredicate를 이용해서 당첨 순위를 구해보자

Hyunta·2022년 3월 6일
1

로또 미션

목록 보기
6/6

페어 프로그래밍을 하면서 어떻게 등수를 결정할 지 고민을 했었다. 결론부터 말하면 정답갯수와 보너스넘버를 갖고있는지 두 매개변수를 전달하는 메서드를 만들고, 만약 정답갯수가 5개일 때 보너스넘버를 이용해서 2등과 3등을 구분하는 메서드를 이용했었다. 이렇게 구현하면 아래왜 같이 두가지 메서드가 필요하다.

public static LottoRank valueOf(int sameCount, boolean bonus) {
    if (sameCount == 5) {
        checkSecondOrThird(bonus);
    }
    return Arrays.stream(values())
            .filter(lottoRank -> lottoRank.getCorrectNumber() == sameCount)
            .findFirst()
            .orElseThrow(IllegalArgumentException::new);
}

private static LottoRank checkSecondOrThird(boolean bonus) {
    if (bonus) {
        return SECOND;
    }
    return THIRD;
}

구현하면서도 뭔가 복잡하고 메서드를 두개 쓰는게 마음에 안들었는데, 이번에 네오가 강의를 하면서 BiPredicate에 대해서 알려주면서 깔끔하게 구현할 수 있는 방법을 배웠다.


BiPredicate는 무엇인가?

  • 말 그대로 두개의 argument를 받아와 predicate하는 함수형 인터페이스이다.
  • test() 메서드를 이용하면 boolean 값을 반환해준다.

적용

public enum LottoRank {
    NOTHING(0, 0, (correctNumber, matchBonus) -> correctNumber < 3),
    FIFTH(3, 5000, (correctNumber, matchBonus) -> correctNumber == 3),
    FOURTH(4, 50000, (correctNumber, matchBonus) -> correctNumber == 4),
    THIRD(5, 1500000, (correctNumber, matchBonus) -> correctNumber == 5 && !matchBonus),
    SECOND(5, 30000000, (correctNumber, matchBonus) -> correctNumber == 5 && matchBonus),
    FIRST(6, 2000000000, (correctNumber, matchBonus) -> correctNumber == 6);
    
    private final int correctNumber;
    private final int prizeAmount;
    private final BiPredicate<Integer, Boolean> isMatch;

...

    public static LottoRank valueOf(int sameCount, boolean bonus) {
        return Arrays.stream(values())
                .filter(lottoRank -> lottoRank.isMatch.test(sameCount, bonus))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("[ERROR] 조건에 맞지 않는 당첨입니다."));
    }

Enum에 BiPredicate 값을 추가하고 valueOf()를 호출할 때 BiPredicate를 통해서 확인할 수 있게된다. 위에 메서드를 두개로 분리했었는데 이를 하나로 통합할 수 있다. 그리고 enum의 상수에 조건이 같이 명시되어 당첨조건을 한눈에 볼 수 있어서 더 좋은 것 같다.

요약

BiPredicate는 argument 두개를 받아 boolean으로 반환하는 함수형 인터페이스이다.

함수형 인터페이스도 나중에 공부해보고 단순히 기능을 쓰는 것이 아니라, 스트림과 람다식을 이해하고나서 애용할 것 같다!

Reference

https://docs.oracle.com/javase/8/docs/api/java/util/function/BiPredicate.html

profile
세상을 아름답게!

0개의 댓글