

public static void main(String[] args) {
final Set<Integer> numSet = new HashSet<>();
final List<Integer> numList = new ArrayList<>();
final List<Integer> userNumList = new ArrayList<>();
while (numSet.size() < 3) {
// random 메소드를 통해 1~9 숫자 생성
numSet.add((int) (Math.random() * 9) + 1);
}
System.out.println(numSet.toString());
}
문제발생 : 숫자야구 생성을 위한 랜덤숫자 3개를 생성시키고 중복제거를 위해 HashSet()을 사용중 값이 계속 정렬된 상태로 저장되는것을 확인. 정렬된상태를 유지한다면 셔플 및 알고리즘 로직이 완전히 달라져버림.
가설 : Set은 값을 정렬된상태로 인덱스를 비교하여 저장 연산을 실행하는가?
원인 : 결론부터 말하자면 HashSet은 정렬을 지원하지 않는다. HashSet에 데이터가 들어가며 테이블인덱스의 연산때문에 그렇게 보이는것.


// 게임 시작시 3개의 숫자를 생성. Set으로 중복을 제거하고 List로 변환시켜 셔플.
public void addNum() {
while (numSet.size() < 3) {
// random 메소드를 통해 1~9 숫자 생성
numSet.add((int) (Math.random() * 9) + 1);
}
numList.addAll(numSet);
Collections.shuffle(numList);
System.out.println("< 게임을 시작합니다 >");
}

4. 문제해결 : Set을 List에 담아서 Collections.shuffle(); 메소드를 활용하여 랜덤한 순서로 바뀔수 있게 문제해결.
참조 :

456 등으로 받아 하나씩 쪼개어 중복, 0의 경우의 처리는 성공하였으나 해당 문자가 숫자인가? 에 대한 조건식의 부재발생.
// 입력값 유효성 검사
if (userNum.length() >= 4) {
System.out.println("숫자를 3자리로 입력해주세요.");
} else {
// 문자열을 나누어서 각각의 int 타입 숫자로 일의 자릿수로 저장,
for (int i = 0; i < userNum.length(); i++) {
char c = userNum.charAt(i);
// 입력값 유효성검사.
if (userNumList.contains(Character.getNumericValue(c)) || Character.getNumericValue(c) == 0 || !Character.isDigit(c)) {
System.out.println("올바르지 않은 입력값입니다.");
userNumList.clear();
break;
} else {
// 올바른 데이터일 경우 List add
userNumList.add(Character.getNumericValue(c));
}
}
참조 :
https://velog.io/@dyko/string-isNumberic
https://jamesdreaming.tistory.com/157

public class LabeledBreakExample {
public static void main(String[] args) {
outerLoop:
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
System.out.println("i: " + i + ", j: " + j);
if (i * j == 9) {
break outerLoop; // outerLoop 라벨이 붙은 반복문을 종료
}
}
}
System.out.println("End of the outer loop.");
}
}
while문에서의 조건을 false로 바꾸는 로직 이지만 컨트롤하기가 너무 껄끄럽다.Labeled Loop 기법으로 Loop문에 이름표인 라벨을 달아 특정반복문을 명확하게 제어해낼수있다.// 유저가 찬스기능을 활요하는지에 대한 흐름분기 제어
public void useChance(List<Integer> nums) {
System.out.println("현재남은 찬스횟수 : " + getChanceNumber());
System.out.println("찬스를 사용하려면 Y 입력 미사용시 N 입력");
// 루프 라벨기능 추가
Loop1:
while (true) {
String userSelChance = sc.nextLine();
// 대소문자 구분없이 비교
if (userSelChance.equalsIgnoreCase("Y")) {
while (true) {
System.out.println("0. 찬스 사용 중지 1. 정확한 번호 알기(기회 2회 소모) 2. 번호 Up & Down(기회 1회 소모) 3. 모든 번호의 합(기회 1회 소모)");
int userSelChanceMenu = sc.nextInt();
if (userSelChanceMenu == 0) {
break Loop1;
} else if (userSelChanceMenu == 1) {
getIndexNumber(nums);
break Loop1;
} else if (userSelChanceMenu == 2) {
getIndexNumberUpDown(nums);
break Loop1;
} else if (userSelChanceMenu == 3) {
getSumAnswer(nums);
break Loop1;
} else {
System.out.println("1, 2 번중 입력해주세요.");
sc.nextLine();
}
}
} else if (userSelChance.equalsIgnoreCase("N")) {
break;
} else {
System.out.println("Y, N 중 입력해주세요.");
}
}
}
참조 : https://sosodev.tistory.com/entry/%EC%9E%90%EB%B0%94-Java-Labeled-Loop