자바 선행학습 3일차 - Random, refactoring, 더블 for문, while & do-while, Date, SimpleDateFormat, equals(), String method

728x90

로또번호 - refactoring 활용 (method) & Thread.sleep() 함수 사용

반복문을 실행하고 결과물을 출력할 때 printf("%2d ")를 사용하여 끝자리 배열이 동일하게 맞춰주었고 해당 코드 블럭이 동일하기 때문에 Alt Shift m(refactoring > extract method)를 사용하여 객체를 생성해 코드를 최적화 시킴.

 

Thread.sleep()의 기본 숫자는 miliseconds부터 시작된다. c, c++, c#, java는 miliseconds로 기본 시작

 - 1000 miliseconds = 1초

따라서 Thread.sleep(1000)을 넣어서 프로그램이 실행이 되게 함.

import java.util.Arrays;
import java.util.Random;

public class LottoNumber {
	public static void main(String[] args) {
//		1.추첨기를 준비
		int[] lotto = new int[45];
		Random random = new Random();
		
//		2.추첨기에 공을 넣고
		for(int i = 0; i<lotto.length; i++) {
			lotto[i]=i+1;
		}
		shuffle(lotto);
		
		System.out.println("\n=============섞기전=============");
//		\n을 넣어서 자리바꿈

//		3.섞는다
//		lotto 배열에 0번째 인덱스 값과 44번째 인덱스 값중에서 랜덤한 위치의 값을 선택해서 두 기억장소의 값을 교환
		for(int i = 0; i<1000; i++) {
			int r = random.nextInt(44)+1;
			int tmp = lotto[0];
			lotto[0] = lotto[r];
			lotto[r] = tmp;
			
		}
		shuffle(lotto);
//		동일한 코드블럭을 잡아서 Alt Shift m or 우클릭 > refactor > extract method 실행
//		옵션 하단값에 replace의 의미는 해당 클래스안에 동일한 코드블럭의 개수를 보여줌
		System.out.println("\n=============섞은후=============");

//		4. 1등 번호 6자리를 출력한다
		for(int i = 0; i<6; i++) {
			System.out.printf("%-2d ",lotto[i]);
			
//		프로그램을 1초 간격으로 실행한다
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		Thread 객체를 import해서 sleep을 사용하면 밀리세컨 단위로 시간 지정 가능
//		1000 miliseconds당 1초
//		강제로 프로그램을 멈추었기때문에 interrupted 메세지가 뜨고 try catch함수를 씀으로써 오류를 해결
		}
		System.out.println("보너스: " + lotto[6]);
		
		
	}

//	method로 작성이 됨 = 같은 작업을 여러번 반복하기 귀찮을 때 객체화 시킴	
	private static void shuffle(int[] lotto) {
		for(int i = 0; i<lotto.length; i++) {
			System.out.printf("%2d ",lotto[i]); 
			if((i+1)%10==0) {
				System.out.println();
			}
		}
	}			
}

//1  2  3  4  5  6  7  8  9 10 
//11 12 13 14 15 16 17 18 19 20 
//21 22 23 24 25 26 27 28 29 30 
//31 32 33 34 35 36 37 38 39 40 
//41 42 43 44 45 
//=============섞기전=============
//14 34 43 26 41 11 27 20 40 39 
//44  1 30 24  2 16 42 29 31  5 
//10  4 32 18 38  8 25  6 35 28 
//23 33 19 12 13 22 37  9 21  3 
//45  7 36 17 15 
//=============섞은후=============
//14 34 43 26 41 11

로또번호 횟수제한 추첨 

금액을 입력하여 1000원 단위마다 1회 씩 반복 실행

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class LottoScanner {
	public static void main(String[] args) {
//		1.추첨기를 준비
		int[] lotto = new int[45];
		Random random = new Random();
		
//		2.추첨기에 공을 넣고
		for(int i = 0; i<lotto.length; i++) {
			lotto[i]=i+1;
		}
		Scanner scanner = new Scanner(System.in);
		System.out.println("복권 구입 금액 입력 (1000원 단위): ");
		int num = scanner.nextInt();
		
		for(int j = 0; j<num/1000; j++) {

//		3.섞는다
//		lotto 배열에 0번째 인덱스 값과 44번째 인덱스 값중에서 랜덤한 위치의 값을 선택해서 두 기억장소의 값을 교환
		for(int i = 0; i<1000; i++) {
			int r = random.nextInt(44)+1;
			int tmp = lotto[0];
			lotto[0] = lotto[r];
			lotto[r] = tmp;
		}

//		4. 1등 번호 6자리를 출력한다
			for(int i = 0; i<6; i++) {
				System.out.printf("%-2d ",lotto[i]);
			}
		System.out.println("보너스: " + lotto[6]);
		}
		System.out.println("거스름돈: "+ (num - ((num/1000)*1000)));
	}
}

출력문:
복권 구입 금액 입력 (1000원 단위): 
3546
24 6  14 42 17 4  보너스: 2
12 1  18 19 23 5  보너스: 20
42 18 37 11 12 28 보너스: 13
거스름돈: 546

While 무한루프를 이용한 지정 메뉴 출력

무한루프 반복문은 loop이라는 이름을 지정해서 5번을 입력하면 무한 반복문 탈출하여 프로그램 종료

 - Ctrl + Shift +o를 누르면 불필요한 import 모두 삭제 (은근한 있어보이는 꿀팁?)

import java.util.Random;
import java.util.Scanner;
import java.util.Arrays;

//Ctrl + Shift + O누르면 불필요한 import를 다 지워줌
public class WhilePracticeMenuTest {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int menu = 0;
		
//		for(;;) { //무한 루프로 아래 하단의 반복문을 무한으로 반복시킴
		loop: while(true) {// 반복문의 이름을 지정해서 무한반복문을 종료시킴
		do {
			System.out.println("======================================");
			System.out.println("1. 입력 2. 목록보기 3. 수정 4. 삭제 5. 종료 ");
			System.out.println("======================================");
		System.out.println("원하는 메뉴를 입력하세요: ");
		menu = scanner.nextInt();
		}
		while(1>menu || menu>5);
//		반복문을 탈출했다면 menu의 숫자가 1~5사이에서 입력되었다는 의미
		switch(menu) {
			case 1: System.out.println("입력"); break;
			case 2: System.out.println("목록보기"); break;
			case 3: System.out.println("수정"); break;
			case 4: System.out.println("삭제"); break;
			case 5: System.out.println("프로그램 종료"); break loop;

//			프로그램 강제 종료 = System.exit(0) 강제종료
//			case 5: System.out.println("프로그램 종료");
//			System.exit(0); break;
		
//			아니면 while(menu!=5)로 조건을 주어서 case5의 조건을 지우고
//			두번째 while 반복문의 대괄호 밖에 break;를 넣어주면 됨
			}
		}
	}
}

현재 날짜 구해서 요일 출력하기

현재 년월일을 입력하여 윤년의 개수를 빼고 당일 해당년이 윤년이면 29 or 28일을 대입한 후 해당 월의 지난 날을 합산해서 7로 나눠 당일의 요일을 출력하는 코딩

import java.util.Scanner;

public class YearDatePractice {
	public static void main(String[] args) {
//		2021 1 19일 = 변수에 각각 넣고 무슨 요일(수 화)인지 출력
//		요일 계산 = 서기 1년 1월 1일(월요일) 을 기반으로 계산
//		따라서 현재날짜 - 서기 1년 1월 1일 = 현재요일 (7으로 나눠서 1이 나오면 월 2 화 등등)
		Scanner scanner = new Scanner(System.in);
		System.out.println("요일을 출력할 년, 월, 일을 입력하세요");
		int year = scanner.nextInt();
		int month = scanner.nextInt();
		int day = scanner.nextInt();
//		서기 1년 1월 1일부터 입력한 날짜까지의 일수의 개수를 구한다
//		당년은 다 지나지 않았으므로 전년도 12월 (365일)까지 구하고
		
		int sum = (year-1) + (year - 1)/4 - (year - 1) / 100 + (year - 1)/400 * 365;
		//4에 나눠떨어지는 년 과 100에 나눠떨어지는 연수를 빼고
//		400에 나눠떨어지는 개수를 더하면 윤년개수를 뺄 수 있음	

		System.out.println(sum);
//		서기 1년부터 총 738155 일이 구해짐
		
//		전년도 12월 31일까지 지난 날짜에 전달까지 지난 날짜를 더한다.
//		month - 1 = 이번달은 다 지나가지 않았기 때문에 -1을 해줌
		
		
//		=====================switch 통해서 구한 값=====================
//		
//		for(int i = 1; i<=month-1; i++) {
//			switch(i) {
////				case 1: sum+=31; break; 
////				case 2: sum+=28; break; 
////				case 3: sum+=31; break; 
////				case 4: sum+=30; break; 
////				case 5: sum+=31; break; 
////				case 6: sum+=30; break; 
////				case 7: sum+=31; break; 
////				case 8: sum+=31; break; 
////				case 9: sum+=30; break; 
////				case 10: sum+=31; break; 
////				case 11: sum+=30; break; 
////				case 12: sum+=31; break; 
//			
////			위의 긴 공식을 아래와 같이 짧게 코딩 가능
//				
//				case 2: 
//					sum += (year % 4 == 0 && year % 100 ==0 || year % 400 == 0) ? 29 : 28;
////					현재 년이 윤년인지 확인해야 하기 때문에 삼항연산자를 사용해서 29일 혹은 28일을 더하는 조건을 생성
//					break;
//				case 4: case 6: case 9: case 11:
//					sum +=30;
//					break;
//				default: 
//					sum +=31;
//					break;
//				
//			}		
//			=====================switch 통해서 구한 값=====================
		
//		=====================array 통해서 구한 값=====================
		int[] m = {31,28,31,30,31,30,31,31,30,31,30,31};
//		2월의 마지막 날짜 확정
		m[1] = year % 4 == 0 && year % 100 ==0 || year % 400 == 0 ? 29 : 28;
		
		for(int i = 1; i<month; i++) {
			sum+= m[i-1];// i가 1부터 시작하기 때문에 -1을 해주어서 0번째 인덱스부터 실행하게 해줌
		
		}
//		=====================array 통해서 구한 값=====================
		
//		현재 달의 날짜를 sum에 더한다
		sum += day;
		
		System.out.println(sum % 7);
		
		String[] d = {"월요일","화요일","수요일","목요일","금요일","토요일","일요일"};
			System.out.println(d[sum%7-1]);

////		=====================switch 통해서 구한 값=====================
//		switch(sum%7) {
//		case 0: System.out.println("월요일"); break;
//		case 1: System.out.println("화요일"); break;
//		case 2: System.out.println("수요일"); break;
//		case 3: System.out.println("목요일"); break;
//		case 4: System.out.println("금요일"); break;
//		case 5: System.out.println("토요일"); break;
//		case 6: System.out.println("일요일"); break;
//		}
////		=====================switch 통해서 구한 값=====================
	}	
}

//출력값:
//요일을 출력할 년, 월, 일을 입력하세요
//2022 1 19
//738155 > 2022년까지 총 일 수
//3
//수요일

Date 객체를 활용한 현재 date 출력

Date & sdf(SimpleDateFormat()) 사용하여 현재 컴퓨터 시간 출력

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DataTest {
	public static void main(String[] args) {
	//Date 클래스 사용
	Date date = new Date();
	System.out.println("Date객체를 사용한 컴퓨터 시간 출력: "+ date);
//	현재 컴퓨터의 값에 저장되있는 한국 표준시를 가져옴
	
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 E요일 HH시 mm분 ss초");
//	sdf ctrl space ㄱ
	System.out.println("sdf를 사용한 서식 지정 date 출력: "+sdf.format(date));
//	프린트를 이용하여 .format()을 사용해주면 지정해놓은 서식대로 날짜 출력 가능
	
	SimpleDateFormat sdf2 = new SimpleDateFormat("yy.MM.dd(E) a h:mm:ss.SSS");
	System.out.println(sdf2.format(date));
	
//	Date는 1900년 기준으로 날짜를 처리하므로 년도는 1900을 더해서 얻어와야하고 월은 1을 더해서 얻어와야 한다.
//	가운데 줄 그어진건 지금 새로운 버전이 있으므로 새로운걸 쓰라는 추천의 의미. 다만 아래도 실행은 가능하다.
	System.out.println("년 :" + (date.getYear()+1900));
	System.out.println("월: "+ (date.getMonth()+1));
	System.out.println("일: " + date.getDate()); //date가 일이고 요일이 day이다
	System.out.println("요일: " + date.getDay());
	System.out.println("시: "+ date.getHours());
	System.out.println("분: "+ date.getMinutes());
	System.out.println("초: "+ date.getSeconds());
	
	System.out.println();
//	새로운 Date 클래스 = Calendar
//	new 를 쓰지못하는 이유는 Calendar 자체에 객체가 있기 때문. 따라서 .getInstance라는 함수를 사용하여
//	자체 인스턴스 변수를 가져와서 안의 값을 사용
	Calendar cal = Calendar.getInstance();
	System.out.println(cal.getWeekYear());
	System.out.println(sdf2.format(cal.getTime()));
//	서식에 맞춰 출력가능한데 위와 같이 .format(안에 cal.getTim())함수로 불러와야 적용가능
	System.out.println("년:" + cal.get(Calendar.YEAR));
	System.out.println("월:" + cal.get(Calendar.MONTH)+1);
	System.out.println("일:" + cal.get(Calendar.DATE));
	System.out.println("일:" + cal.get(Calendar.DAY_OF_MONTH));
	System.out.println("요일:" + cal.get(Calendar.DAY_OF_WEEK));
//	Calendar은 일요일이 1이고 Date함수는 0이 일요일
	System.out.println("시간:" + cal.get(Calendar.HOUR)); //12시간제
	System.out.println("시간:" + cal.get(Calendar.HOUR_OF_DAY)); //24시간제
	System.out.println("분:" + cal.get(Calendar.MINUTE));
	System.out.println("초:" + cal.get(Calendar.SECOND));
	System.out.println("밀리초:" + cal.get(Calendar.MILLISECOND));
	
	System.out.println();
	
//	System.currentTimeMillis 메소드는 1970년 1월 1일 자정부터 이 메소드가 실행되는 순간까지 지난 시간을
//	1/1000초로 환산해서 얻어옴
	long start = System.currentTimeMillis(); //13자리의 정수이기 때문에 long으로 출력해줘야됨
	System.out.println(sdf2.format(start));
//	SimpleDateFormat을 사용해서 지정된 서식을 통해 위와같이 시간 출력	
	

	
	}
}
//Date객체를 사용한 컴퓨터 시간 출력: Wed Jan 19 16:57:26 KST 2022
//sdf를 사용한 서식 지정 date 출력: 2022년 01월 19일 수요일 16시 57분 26초
//22.01.19(수) 오후 4:57:26.868
//년 :2022
//월: 1
//일: 19
//요일: 3
//시: 16
//분: 57
//초: 26
//
//2022
//22.01.19(수) 오후 4:57:26.996
//년:2022
//월:01
//일:19
//일:19
//요일:4
//시간:4
//시간:16
//분:57
//초:26
//밀리초:996
//
//22.01.19(수) 오후 4:57:26.997

아래의 링크에서 Date의 서식을 확인할 수 있는 java api를 확인할 수 있다.

https://docs.oracle.com/javase/8/docs/api/

 

Java Platform SE 8

 

docs.oracle.com

 

아래의 빨간 점이 자주 쓰이므로 참고할 것


String 객체값의 주소 저장 개념 + equals 사용하여 비교하기

String + Class의 변수 값은 .equals()로 비교하자

 - 결론 .equals()를 사용하는 것이 멘탈이 좋아짐

public class StringTest {
	public static void main(String[] args) {
	
//		문자열이 만들어지면 문자열을 메모리에 저장시키고 그 메모리 주소를 문자열 변수에 저장시킴
//		따라서 AAA를 출력하는 것이 아니라 AAA가 저장되있는 주소를 출력하는 것
		String str1 = "AAA";

//		동일 문자열이 메모리에 존재한다면 해당 문자열을 변수에 직접 저장한다.
		String str2 = "AAA";
		
		if(str1.equals(str2)) 
			System.out.println("같다");
		else
			System.out.println("다르다");
		
//		원칙적으로 String도 클래스이기 때문에 객체를 만들듯이 new를 사용해서 새로 지정하는 게 원본표현
//		new를 사용해서 문자열을 만들면 메모리에 같은 내용의 문자열이 있더라도 다시 만들고
//		그 다른 주소를 다시 변수에 저장한다.
		String str3 = new String("AAA");
	
//		따라서 아래의 값은 변수의 값이 같더라도 주소가 다르기 때문에 '다르다'라는 값을 가짐
//		>new String 으로 재생성했기때문에 주소가 다르다
		if(str1 == str3)
			System.out.println("같다");
		else
			System.out.println("다르다");

//		결론:
//		문자열은 '=='로 비교하지 말고 .equals() method로 비교할 것

//		'=='을 사용해서 비교할 수 있는 값: 기본자료형 8가지 & null(class)
//		> 문자열 & 클래스로 만든 객체의 저장값은 equal()사용
		if(str1.equals(str3))
			System.out.println("같다");
		else
			System.out.println("다르다");
	}
}

//출력본:
//같다
//다르다
//같다

String 출력, slicing 방법

length(), trim(), toUpperCase, toLowerCase, indexOf, contains, substring, 

import java.util.Scanner;

public class StringMethod {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("영문자 입력");
		String str = scanner.nextLine();

		System.out.println("입력받은 영문자 글자 개수(불필요한 공백 포함): " + str.length());
		
//		문자열 앞뒤 공백 지우는 method = .trim()
//		> 메소드의 실행은 왼쪽부터 오른쪽으로 가는 개념
//		다만 글자 사이의 공백은 지워지지 않음
		System.out.println("입력받은 영문자 글자 개수(공백 제외): " + str.trim().length());

		for(int i = 0; i < str.length(); i++) {
			System.out.println(i + "번째 문자: "+ str.charAt(i));
		}
//		입력된 소문자를 대문자로 바꿔 출력하기 
		for(int i = 0; i < str.length(); i++) {
//			소문자인지 확인하기, 유니코드 사용
			if('a' < str.charAt(i) && str.charAt(i) < 'z') {
//				char 2바이트, int 4바이트기 때문에 계산식을 먼저 괄호로 묶어주고 char로 casting하여 출력
				System.out.print((char)(str.charAt(i)-32));
			}
			else {
				System.out.print(str.charAt(i));
			}
		}
		System.out.println();
		
//		대문자 & 소문자 method
		System.out.println("무조건 대문자: " + str.toUpperCase());
		System.out.println("무조건 소문자: " + str.toLowerCase());
		
//		indexOf()

//		문자열에서 특정 문자열의 자리를 찾는 method. 특정 문자열의 시작 자리를 출력해준다
		System.out.println("문자열에서 'im'의 위치: "+ str.indexOf("im"));
//		lastindexOf는 문자열의 뒤에서 위치를 얻어오지만 자리 인덱스 표시값은 좌측에서 우측으로 동일하다
//		대소문자를 구분하기 때문에 toLowerCase()를 붙여서 오류가 나지 않도록 함
		System.out.println("문자열에서 'im'의 위치: "+ str.toLowerCase().lastIndexOf("im"));
//		특정 문자열에서 찾는 문자열이 없으면 -1을 얻어와서 출력
		System.out.println("문자열에서 'uo'의 위치: "+ str.lastIndexOf("uo"));

//		contains

//		문자열 포함 여부 method
//		포함되있으면 true 없으면 false = boolean 값 출력
		System.out.println("'im'의 포함 여부: "+ str.contains("im"));
		System.out.println("'uo'의 포함 여부: "+ str.contains("uo"));
		
//		substrings()
		
//		문자열 슬라이싱하는 방법
//		[3:0]까지 슬라이싱 - 0부터 오는 것이 아니라 3의 시작점부터 끝까지 출력함
		System.out.println(str.substring(3));
//		[3:5]까지 슬라이싱
		System.out.println(str.substring(0, 3));
	}
}

//영문자 입력
//timsim
//입력받은 영문자 글자 개수(불필요한 공백 포함): 6
//입력받은 영문자 글자 개수(공백 제외): 6
//0번째 문자: t
//1번째 문자: i
//2번째 문자: m
//3번째 문자: s
//4번째 문자: i
//5번째 문자: m
//TIMSIM
//무조건 대문자: TIMSIM
//무조건 소문자: timsim
//문자열에서 'im'의 위치: 1
//문자열에서 'im'의 위치: 4
//문자열에서 'uo'의 위치: -1
//'im'의 포함 여부: true
//'uo'의 포함 여부: false
//sim
//tim
728x90