- 7월에 교육 마치면서, 이것 저것 일정이 겹친 덕분에 이제서야 소스코드 머지 된 것을 반영하고 다음 단계로 넘어간다. step3로 넘어가기 전에 리뷰어님의 리뷰를 최대한 반영했다. 개인적으로 소스코드가 마음에 안들어서 확..뒤집고 싶지만 일단 점진적으로 바꿔보자는 말씀에 그러기로 했다.
- 리뷰어님이 말씀주신 개선 할 점은 두 가지로 하기에 그 내용과 해결과정을 정리해 두었다. |
1
2
3
4
5
6
7
8
9
|
public static Set<List<Integer>> purchasedLottos(int lottoCount) {
Set<List<Integer>> collectAutoLotto = new HashSet<>();
while (collectAutoLotto.size() < lottoCount) {
List shuffleLottoNumbers = generateAutoLotto();
collectAutoLotto.add(new ArrayList<>(shuffleLottoNumbers));
}
return collectAutoLotto;
}
|
1. 해당 코드 중 List 부분을 Class로 빼내기
- 결국, 일급콜렉션을 쓰라는 것과 일맥상통하는 이야기 같다.
- Set<List<Integer>> 처럼.. 특정 자료형 안에 또 어떤 자료형을 넣는게 굉장히 보기싫다..
- 분리하고 싶지만 어떻게 분리해야하는 걸까?
- class로 나도 빼고 싶은데, 방법을 모르겠다..
- 본 포스팅 내용과 소스코드는 [점프 투 자바 - 클래스] 편을 바탕으로 포스팅 함. ( 클릭하면 사이트 이동 )
List<Integer> 부분을 class로 빼냈다.. 이게 이소리였구나..
1
2
3
4
5
6
7
8
9
10
11
12
|
public class Lotto {
static final int LOTTO_NUMBER_MIN = 1;
static final int LOTTO_NUMBER_MAX = 45;
private List<Integer> lotto;
public Lotto (List<Integer> lotto) {
this.lotto = new ArrayList<>(lotto);
}
}
|
▶이렇게 Lotto.java 의 클래스를 만들고, 하기 LottoGenerator.java에서 사용했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class LottoGenerator {
// 소스코드 중략..
public static Set<Lotto> purchasedLottos(int lottoCount) {
Set<Lotto> collectAutoLotto = new HashSet<>();
while (collectAutoLotto.size() < lottoCount) {
List<Integer> shuffleLottoNumbers = generateAutoLotto();
collectAutoLotto.add(new Lotto(shuffleLottoNumbers));
}
return collectAutoLotto;
}
private static List<Integer> generateAutoLotto() {
Collections.shuffle(standardLotto);
List<Integer> shuffleLottoNumbers = standardLotto.subList(0, 6);
Collections.sort(shuffleLottoNumbers);
return shuffleLottoNumbers;
}
}
|
1) 클래스
- java class 파일을 만들면 클래스 생성 된 것 아닌가?
: 클래스의 선언만 있고 내용이 없기 때문에, 껍데기만 있는 클래스를 생성한 것이다.
(cat이라는 객체가 없으면 Animal 이라는 클래스는 껍데기)
- 하지만, 이 껍데기가 있어야 객체를 만들 수 있다.
1
2
3
4
|
public class Animal {
Animal cat = new Animal();
}
|
- cat이라는 객체가 없으면 Animal 이라는 클래스는 껍데기
- Animal cat = new Animal(); : new는 객체를 생성할 때 사용하는 키워드이다. 이 코드로 Animal 클래스의 인스턴스인 cat이 생성된다. 즉, Animal의 객체가 만들어 진다.
cat + @ | 객체와 인스턴스 |
cat 은 객체다. cat 은 Animanl의 인스턴스이다. cat은 Animal 클래스의 인스턴스이다. ▷ Animal이라는 클래스 안에 다양한 동물 객체들을 만들 수 있다. Animal monkey = new Animal(); Animal rabbit = new Animal(); ... |
- 클래스에 의해서 만들어진 객체를 인스턴스라고도 한다. (객체 ≒ 인스턴스) - 인스턴스: 특정 객체가 어떤 클래스의 객체인지 관계 위주로 설명할 때 사용한다. 하기 표현을 예로 어떤 표현이 더 적합한지 참고하자. (부등호 방향 = 더 적합한 표현) ▷ cat 은 인스턴스 <<< cat 은 객체 ▷ cat 은 Animal의 인스턴스 >>> cat 은 Animal의 객체 |
2) 객체 변수( Instance Variable )
- Animal이라는 껍데기 클래스를 좀 더 발전시켜 보자
- Animal 클래스에 의해 만들어지는 동물들에 이름을 지어주자.
1
2
3
|
public class Animal {
String name;
}
|
- String name; 처럼 클래스에 선언 된 변수를 객체 변수라고 부른다. (= 인스턴스 변수, 멤버변수, 속성)
- 클래스에 의해 생성 되는 것은 객체, 그리고 그 클래스에 선언 된 변수는 객체 변수라고 생각하면 쉽다.
- 객체.객체변수 : 객체 변수는 도트연산자(.)을 이용하여 접급 할 수 있다. (예: cat.name;)
1
2
3
4
5
6
7
|
public class Animal {
String name;
public static void main(String[] args) {
Animal cat = new Animal();
System.out.println(cat.name); // 대입한 값이 없으므로, 실행 시 null 출력
}
}
|
★ 객체 변수는 공유되지 않는다. 객체 변수의 값은 독립적으로 유지 된다.
- 아래 코드에서 cat과 dog의 name은 각각 boby, happy로 다름을 알 수 있다. 즉, name이라는 객체변수는 공유되지 않는다는 것을 알 수 있다. 이것은 객체 변수의 값이 독립적으로 유지됨을 보여주는 것이다. 이 점이 클래스의 존재 이유다.
1
2
3
4
5
6
7
8
9
10
|
public static void main(String[] args) {
Animal cat = new Animal();
cat.setName("boby");
Animal dog = new Animal();
dog.setName("happy");
System.out.println(cat.name);
System.out.println(dog.name);
}
|
▶여기까지 했다면? 객체변수에 접근하는 방법/ 값이 할당 되어 있지 않은 상태에 대해서 알게 되었다.
3) 메소드
- 객체 변수에 값을 대입하는 방법 중 하나.
- 클래스 내에 구현된 함수.
- Animal 클래스의 객체 변수인 name 에 값 대입해 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Animal {
String name;
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Animal cat = new Animal();
cat.setName("boby");
System.out.println(cat.name);
}
}
|
- cat.setName("boby"); 객체가 메소드를 호출하기 위해서는 '객체.메소드' 로 호출 가능하다.
- this.name = name ▶ cat.name = "boby"; 나 마찬가지다.
- this는 Animal 클래스에 의해서 생성된 객체를 지칭한다.
1
2
3
4
5
6
7
8
9
|
public class LottoApplication {
// 소스코드 중략..
int[] winningNumbers = inputWinningNumbers();
List<Integer> resultMatcing = Lotto.lotteryStatics(purchasedLottos, winningNumbers);
// 이하 생략
}
|
2. '이펙티브자바 아이템 28. 배열보다는 리스트를 사용하라' 를 참고하여, 리팩토링하기
- winningNumbers를 배열이 아닌 리스트로 사용하란 이야기
- 그럼 winningNumber랑 연계 된 다른 메소드까지 쫙 바꿔주어야 한다.
- 배열보다 리스트를 사용하라고 권고하는 이유는 뭘까? 하기 링크를 참고하면 좋다
https://github.com/ryudung/effective-java3-E/tree/master/src/test/java/ch05/item28
https://sjh836.tistory.com/171
대충 내용을 요약하자면, 리스트를 쓰면 타입의 안정성을 얻을 수 있고, 컴파일 단계에서 오류를 쉽게 발견할 수 있다.
1번 해결시간보다는 덜 걸렸고, 애초에 입력받을 때 Array로 받기 때문에 입력받고 값을 넘겨주는 부분에서 수정 할 수 밖에 없었다.
- scanner 로 입력받음 -> trim을 이용해서 값을 쪼개어 저장하는 형식이 입력값에 대한 처리를 가장 수월하게 하는 방법이라 생각
- 더 유용한 방법이 있을 수 있지만 로또 프로그램의 전체적인 그림에서 값 입력 처리부분이 핵심 코드가 아니므로.. 여기에 시간을 많이 할애하지 않기로 했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public static ArrayList<Integer> inputWinningNumbers1() {
System.out.println("지난 주 당첨 번호를 입력해 주세요.");
String[] inputWinningNumbers = scan.nextLine().split(",");
String[] trimWinningNumbers = new String[LottoGenerator.WINNING_NUMBERS_LENGTH];
for (int i = 0; i < LottoGenerator.WINNING_NUMBERS_LENGTH; i++) {
trimWinningNumbers[i] = inputWinningNumbers[i].trim();
}
InputValidationCheck.checkWinningNumberLength(trimWinningNumbers);
InputValidationCheck.checkOverlapWinningNumber(trimWinningNumbers);
int[] winningNumbers = InputValidationCheck.checkWinningNumberRange(trimWinningNumbers);
Arrays.sort(winningNumbers);
// 추가한 소스코드
ArrayList<Integer> inputWinningNumberList = new ArrayList<>();
for(int i = 0; i < LottoGenerator.WINNING_NUMBERS_LENGTH; i++) {
inputWinningNumberList.add(winningNumbers[0]);
}
return inputWinningNumberList;
}
|
* ArrayList와 List 차이 알아두기
'개발 이야기 > CC-Java' 카테고리의 다른 글
[2주차] 로또게임 - 일급콜렉션(2주차 핵심내용) (0) | 2019.09.06 |
---|---|
[2주차] 로또게임 - Step2. 피드백 (0) | 2019.07.18 |
[1주차] 자동차 경주 게임 - Step3. 피드백(4)_추상화 (0) | 2019.07.03 |
[1주차] 자동차 경주 게임 - Step3. 피드백(3)_Interface (0) | 2019.07.02 |
[1주차] 자동차 경주 게임 - Step3. 피드백(2)_변수의 scope와 static (0) | 2019.07.02 |