@@ -1,68 +1,75 @@
 package domain;
 
+import static domain.WinningStatistics.THRESHOLD;
+
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
 public enum WinningPrizes {
-    MISS(0, 0) {
-
-    },
-    FIFTH_PRIZE(5, 5_000),
-    FOURTH_PRIZE(4, 50_000),
-    THIRD_PRIZE(3, 1_500_000),
-    SECOND_PRIZE(2, 3_000_000),
-    FIRST_PRIZE(1, 2_000_000_000);
-
-    public static final int OFFSET = 3;
+    ZERO(0, false, 0, 0, count -> THRESHOLD),
+    ONE(1, false,0, 0, count -> THRESHOLD),
+    TWO(2, false, 5, 5_000, count -> THRESHOLD),
+    THREE(3, false, 5, 5_000, count -> count),
+    FOUR(4, false, 4, 50_000, count -> count),
+    FIVE(5, false, 3, 1_500_000, count -> count),
+    FIVE_BONUS(5, true, 2, 3_000_000, count -> count),
+    SIX(6, false, 1, 2_000_000_000, count -> count);
 
-    private static final Map<Integer, WinningPrizes> WINNING_PRIZES_MAP = new HashMap<>();
+    private static final int HASH_GENERATION_NUMBER = 31;
+    private static final Map<Integer, WinningPrizes> WINNING_PRIZE_MATCHERS_MAP = new HashMap<>();
 
-    static {
-        for (WinningPrizes value : values()) {
-            WINNING_PRIZES_MAP.put(value.rank, value);
-        }
-    }
 
+    private int numberOfCount;
+    private boolean isBonusMatch;
     private int rank;
-    private final int prizeMoney;
+    private int prizeMoney;
+    private Function<Integer, Integer> countSupplier;
 
-    WinningPrizes(int rank, int prizeMoney) {
+
+    WinningPrizes(int numberOfCount, boolean isBonusMatch, int rank, int prizeMoney, Function<Integer, Integer> countSupplier) {
+        this.numberOfCount = numberOfCount;
+        this.isBonusMatch = isBonusMatch;
         this.rank = rank;
         this.prizeMoney = prizeMoney;
+        this.countSupplier = countSupplier;
     }
 
-    public int calculatePrizeMoney(int count) {
-        return prizeMoney * count;
+    static {
+        for (WinningPrizes value : WinningPrizes.values()) {
+            WINNING_PRIZE_MATCHERS_MAP.put(getHashCode(value.numberOfCount, value.isBonusMatch), value);
+        }
     }
 
-    public int getPrizeMoney() {
-        return prizeMoney;
+    public static int getHashCode(int numberOfCount, boolean isBonusMatch) {
+        int bonusNum = 0;
+        if (isBonusMatch) {
+            bonusNum = 1;
+        }
+        return numberOfCount * HASH_GENERATION_NUMBER + bonusNum;
     }
 
-    public int getRank() {
-        return rank;
+    public static WinningPrizes valueOf(int numberOfCount, boolean isBonusMatch) {
+        isBonusMatch = checkBonus(numberOfCount, isBonusMatch);
+        return WINNING_PRIZE_MATCHERS_MAP.get(getHashCode(numberOfCount, isBonusMatch));
     }
 
-    public static WinningPrizes valueOf(int countOfMatch, boolean matchBonus) {
-        if (countOfMatch < OFFSET) {
-            return WinningPrizes.MISS;
-        }
-
-        if (WinningPrizes.SECOND_PRIZE.rank == countOfMatch) {
-            return decideSecondOrThirdPrizes(matchBonus);
+    private static boolean checkBonus(int numberOfCount, boolean isBonusMatch) {
+        if (FIVE_BONUS.getNumberOfCount() != numberOfCount && isBonusMatch) {
+            isBonusMatch = false;
         }
+        return isBonusMatch;
+    }
 
-        return WINNING_PRIZES_MAP.get(countOfMatch);
+    public int calculatePrizeMoney(int count) {
+        return prizeMoney * count;
     }
 
-    public static WinningPrizes valueOf(int rank) {
-        return WINNING_PRIZES_MAP.get(rank);
+    public int getPrizeMoney() {
+        return prizeMoney;
     }
 
-    private static WinningPrizes decideSecondOrThirdPrizes(boolean matchBonus) {
-        if (matchBonus) {
-            return WinningPrizes.SECOND_PRIZE;
-        }
-        return WinningPrizes.THIRD_PRIZE;
+    public int getNumberOfCount() {
+        return countSupplier.apply(numberOfCount);
     }
 }

리뷰: IntFunction을 활용해도 좋을 것 같아요.