Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/LottoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import controller.LottoController;

public class LottoApplication {
public static void main(String[] args) {
LottoController controller = new LottoController();
controller.run();
}
}
40 changes: 27 additions & 13 deletions src/main/java/controller/LottoController.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
package controller;

import domain.Lotto;
import domain.LottoNumber;
import domain.LottoStatistics;
import domain.*;
import view.InputView;
import view.OutputView;

import java.util.List;

public class LottoController {
public static void main(String[] args) {
LottoController controller = new LottoController();
controller.run();
}

private void run() {
public void run() {
int purchaseAmount = InputView.getPurchaseAmount();
List<Lotto> lottos = Lotto.purchaseLottos(purchaseAmount);
List<Lotto> lottos = LottoMachine.generateLottos(purchaseAmount / Lotto.LOTTO_PRICE);
OutputView.printLottos(lottos);

List<LottoNumber> winningNumbers = InputView.getWinningNumbers();
LottoStatistics statistics = Lotto.getStatistics(lottos, winningNumbers);
OutputView.printStatistics(statistics);
Lotto winningLotto = InputView.getWinningLotto();
LottoNumber bonusNumber = InputView.getBonusNumber();

LottoResult result = getLottoResult(lottos, winningLotto, bonusNumber);
OutputView.printResult(result, purchaseAmount);
}

private LottoResult getLottoResult(List<Lotto> lottos, Lotto winningLotto, LottoNumber bonusNumber) {
List<LottoPrize> prizes = lottos.stream()
.map(lotto -> getLottoPrize(lotto, winningLotto, bonusNumber))
.toList();
return new LottoResult(prizes);
}

private LottoPrize getLottoPrize(Lotto lotto, Lotto winningLotto, LottoNumber bonusNumber) {
int matchCount = countMatchingNumbers(lotto, winningLotto);
boolean isMatchBonus = lotto.contains(bonusNumber);
return LottoPrize.matchPrize(matchCount, isMatchBonus);
}

private int countMatchingNumbers(Lotto lotto, Lotto winningLotto) {
return (int) lotto.numbers().stream()
.filter(winningLotto.numbers()::contains)
.count();
}
}
45 changes: 18 additions & 27 deletions src/main/java/domain/Lotto.java
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원시 값 포장을 잘 사용하셨네요! 저는 그냥 1000으로 나눠버렸는데 하나 배워갑니다 :-)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 감사합니다! 그런데 저 부분은 매직넘버를 상수로 선언해서 제거한 부분이고 이번 과제에서 말한 원시값 포장이랑은 다른 개념인 것 같아요..!!

저도 잘은 모르지만
int money; 로 바로 사용하는 게 아니라
Money 클래스를 따로 구현하고 Money money = new Money(int amount);
이런식으로 원시 값을 객체로 포장해서 사용하는 게 원시값 포장인 것 같습니다..!!

돈에 대해선 제가 원시값 포장을 못 했어요🥲 이 부분은 추가로 더 고민해보고 수정하겠습니다!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

죄송해요 저도 어제 스터디에서 설명해주시는 거 듣고 제가 틀렸단 걸 깨달았습니다..전 단순히 포장(감싼다)인 줄 알았어요ㅠㅠ저도 아직 배워야할 게 많은 것 같습니다..ㅠㅠ

Original file line number Diff line number Diff line change
@@ -1,47 +1,38 @@
package domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public record Lotto(List<LottoNumber> numbers) {
public static final int LOTTO_NUMBER_COUNT = 6;
public static final int LOTTO_PRICE = 1000;

public static List<Lotto> purchaseLottos(int purchaseAmount) {
int lottoCount = purchaseAmount / LOTTO_PRICE;
return IntStream.range(0, lottoCount)
.mapToObj(i -> generateLotto())
.collect(Collectors.toList());
public Lotto {
validateNumbers(numbers);
Collections.sort(numbers);
}

private static Lotto generateLotto() {
List<LottoNumber> numbers = new ArrayList<>();
while (numbers.size() < LOTTO_NUMBER_COUNT) {
LottoNumber number = LottoNumber.generate();
if (!numbers.contains(number)) {
numbers.add(number);
}
private void validateNumbers(List<LottoNumber> numbers) {
if (numbers.size() != LOTTO_NUMBER_COUNT) {
throw new IllegalArgumentException("로또 숫자는 6개여야 합니다.");
}
if (numbers.stream().distinct().count() != LOTTO_NUMBER_COUNT) {
throw new IllegalArgumentException("로또 숫자는 중복 되지 않아야 합니다.");
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예외 처리도 잘 하신 것 같아요.

Collections.sort(numbers);
return new Lotto(numbers);
}

public static LottoStatistics getStatistics(List<Lotto> lottos, List<LottoNumber> winningNumbers) {
LottoStatistics statistics = new LottoStatistics();
for (Lotto lotto : lottos) {
int matchCount = getMatchCount(lotto, winningNumbers);
statistics.addCount(matchCount);
}
return statistics;
public static Lotto generate() {
List<LottoNumber> numbers = Stream.generate(LottoNumber::generate)
.distinct()
.limit(LOTTO_NUMBER_COUNT)
.collect(Collectors.toList());
return new Lotto(numbers);
}

private static int getMatchCount(Lotto lotto, List<LottoNumber> winningNumbers) {
return (int) lotto.numbers.stream()
.filter(winningNumbers::contains)
.count();
public boolean contains(LottoNumber number) {
return numbers.contains(number);
}

@Override
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/domain/LottoMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package domain;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class LottoMachine {
public static List<Lotto> generateLottos(int count) {
return Stream.generate(Lotto::generate)
.limit(count)
.collect(Collectors.toList());
}
}
20 changes: 10 additions & 10 deletions src/main/java/domain/LottoNumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@

import java.util.Random;

public record LottoNumber(int value) implements Comparable<LottoNumber> {
private static final int MIN_VALUE = 1;
private static final int MAX_VALUE = 45;
public record LottoNumber(int number) implements Comparable<LottoNumber> {
private static final int MIN_NUMBER = 1;
private static final int MAX_NUMBER = 45;
private static final Random random = new Random();

public LottoNumber {
validateValue(value);
valdateNumber(number);
}

private void validateValue(int value) {
if (value < MIN_VALUE || value > MAX_VALUE) {
private void valdateNumber(final int number) {
if (number < MIN_NUMBER || number > MAX_NUMBER) {
throw new IllegalArgumentException("로또 번호는 1부터 45 사이의 값이어야 합니다.");
}
}

public static LottoNumber generate() {
Random random = new Random();
return new LottoNumber(random.nextInt(MAX_VALUE - MIN_VALUE + 1) + MIN_VALUE);
return new LottoNumber(random.nextInt(MAX_NUMBER - MIN_NUMBER + 1) + MIN_NUMBER);
}

@Override
public String toString() {
return String.valueOf(value);
return String.valueOf(number);
}

@Override
public int compareTo(LottoNumber other) {
return Integer.compare(this.value, other.value);
return Integer.compare(this.number, other.number);
}
}
43 changes: 43 additions & 0 deletions src/main/java/domain/LottoPrize.java
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum을 잘 활용하신 것 같습니다. 저는 enum을 활용할 때 많이 헤맸는데 또 하나 배워갑니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package domain;

import java.util.Arrays;

public enum LottoPrize {
MISS(0, 0, false),
FIFTH(3, 5_000, false),
FOURTH(4, 50_000, false),
THIRD(5, 1_500_000, false),
SECOND(5, 30_000_000, true),
FIRST(6, 2_000_000_000, false);

private final int matchCount;
private final int prize;
private final boolean isMatchBonus;

LottoPrize(final int matchCount, final int prize, final boolean isMatchBonus) {
this.matchCount = matchCount;
this.prize = prize;
this.isMatchBonus = isMatchBonus;
}

public static LottoPrize matchPrize(final int matchCount, final boolean isWithBonus) {
return Arrays.stream(LottoPrize.values())
.filter(prize -> prize.matchCount == matchCount)
.filter(prize -> prize.isMatchBonus == isWithBonus)
.findFirst()
.orElse(MISS);
}

public int getMatchCount() {
return matchCount;
}

public int getPrize() {
return prize;
}

public boolean isMatchBonus() {
return isMatchBonus;
}
}

27 changes: 27 additions & 0 deletions src/main/java/domain/LottoResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package domain;

import java.util.List;

public class LottoResult {
private final List<LottoPrize> prizes;

public LottoResult(List<LottoPrize> prizes) {
this.prizes = prizes;
}

public int getTotalPrize() {
return prizes.stream()
.mapToInt(LottoPrize::getPrize)
.sum();
}

public double getEarningRate(int purchaseAmount) {
return (double) getTotalPrize() / purchaseAmount;
}

public int getCountByPrize(LottoPrize prize) {
return (int) prizes.stream()
.filter(p -> p == prize)
.count();
}
}
26 changes: 0 additions & 26 deletions src/main/java/domain/LottoStatistics.java
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 하신 것 같습니다. PRIZES를 배열로 선언하지 않고 따로 클래스를 생성해서 관리하고(Map을 사용한다던지) 로또 수익 계산을 해도 괜찮을 것 같습니다!

This file was deleted.

20 changes: 15 additions & 5 deletions src/main/java/view/InputView.java
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문자열도 포장을 하시면 좋을 것 같아요. 위에서 원시 값을 포장하신 것처럼요!

Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
package view;

import domain.Lotto;
import domain.LottoNumber;

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class InputView {
private static final Scanner scanner = new Scanner(System.in);

public static int getPurchaseAmount() {
System.out.print("구입금액을 입력해 주세요.\n");
System.out.println("구입 금액을 입력해 주세요.");
return Integer.parseInt(scanner.nextLine());
}

public static List<LottoNumber> getWinningNumbers() {
System.out.print("지난 주 당첨 번호를 입력해 주세요.\n");
return Stream.of(scanner.nextLine().split(","))
public static Lotto getWinningLotto() {
System.out.println("지난 주 당첨 번호를 입력해 주세요.");
String input = scanner.nextLine();
List<LottoNumber> numbers = Arrays.stream(input.split(","))
.map(String::trim)
.map(Integer::parseInt)
.map(LottoNumber::new)
.collect(Collectors.toList());
return new Lotto(numbers);
}

public static LottoNumber getBonusNumber() {
System.out.println("보너스 볼을 입력해 주세요.");
int number = Integer.parseInt(scanner.nextLine());
return new LottoNumber(number);
}
}
35 changes: 23 additions & 12 deletions src/main/java/view/OutputView.java
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문자열을 포장하시고 반복문으로 출력하시면 코드가 훨씬 더 간결해질 것 같습니다.

Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
package view;

import domain.Lotto;
import domain.LottoStatistics;
import domain.LottoPrize;
import domain.LottoResult;

import java.util.List;

public class OutputView {
public static void printLottos(List<Lotto> lottos) {
System.out.printf("%d개를 구매했습니다.\n", lottos.size());
for (Lotto lotto : lottos) {
System.out.println(lotto);
lottos.forEach(System.out::println);
System.out.println();
}

public static void printResult(LottoResult result, int purchaseAmount) {
System.out.println("당첨 통계");
System.out.println("---------");
for (LottoPrize prize : LottoPrize.values()) {
int count = result.getCountByPrize(prize);
printPrizeStatics(prize, count);
}
double earningRate = result.getEarningRate(purchaseAmount);
System.out.printf("총 수익률은 %.2f입니다.%n", earningRate);
}

public static void printStatistics(LottoStatistics statistics) {
System.out.println("\n당첨 통계\n---------");
System.out.printf("3개 일치 (%d원)- %d개\n", statistics.getPrizeFor(3), statistics.getCountFor(3));
System.out.printf("4개 일치 (%d원)- %d개\n", statistics.getPrizeFor(4), statistics.getCountFor(4));
System.out.printf("5개 일치 (%d원)- %d개\n", statistics.getPrizeFor(5), statistics.getCountFor(5));
System.out.printf("6개 일치 (%d원)- %d개\n", statistics.getPrizeFor(6), statistics.getCountFor(6));
System.out.printf("총 수익률은 %.2f입니다.(기준이 1이기 때문에 결과적으로 %s라는 의미임)\n",
statistics.getProfitRatio(),
statistics.getProfitRatio() < 1 ? "손해" : "이익");
private static void printPrizeStatics(LottoPrize prize, int statics) {
if (prize == LottoPrize.MISS) {
return;
}
if (prize.isMatchBonus()) {
System.out.printf("%d개 일치, 보너스 볼 일치(%d원) - %d개%n", prize.getMatchCount(), prize.getPrize(), statics);
return;
}
System.out.printf("%d개 일치 (%d원)- %d개%n", prize.getMatchCount(), prize.getPrize(), statics);
}
}