[Java 기초문법] by Professional Java Developer Career Starter: Java Foundations @ Udemy
While loops
System.console().readline
유저한테 input을 받을 수 있다.
String guessedNum = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
will contain the number that the use enters from the keyboard.
import java.util.Random;
public class GuessIt3 {
public static void main(String[] args) {
int randomNum = new Random().nextInt(10) + 1;
String guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
System.out.printf("The random number was %d. You got it!%n", randomNum);
} else {
System.out.printf("The random number was %d. You didn't got it%n", randomNum);
}
}
}
이대로 실행해보면 IDE가 console 커맨드를 실행하지 못하기 때문에 에러가 난다.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.io.Console.readLine(String, Object[])" because the return value of "java.lang.System.console()" is null
at GuessIt3.main(GuessIt3.java:6)
alt + F12 눌러서 터미널로 이동
터미널에서 자바 실행시키기 (out 폴더에 있는 파일)
이것을 loop으로 돌리지 않았기 때문에 한번 하고 꺼진다.
loop 돌릴 부분을 선택하고 option + command + T (윈도우 Ctrl + Alt + T)
While문으로 작성된 코드
import java.util.Random;
public class GuessIt3 {
public static void main(String[] args) {
int randomNum = new Random().nextInt(10) + 1;
while (true) {
String guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
System.out.printf("The random number was %d. You got it!%n", randomNum);
return;
} else {
System.out.printf("You didn't got it%n", randomNum);
}
}
}
}
While true 부분이 하드코딩 되어 있으니
받는 문자와 비교하는 형식으로 바꿔보자.
그랬을 때 먼저 변수가 선언되어야 하고
선언된 변수가 다시 밑에서 String으로 재선언되어 에러가 나기 때문에
밑에 String을 지워준다.
for the safeguard
그런데 이 문장은 맞으면 ~ 하라는 것이기 때문에 틀렸을 때의 way가 없다.
따라서
while (!"q".equals(guessedNumText)) {
as long as the guessedumtext is NOT q => then run ~
이랬을 때 사용자가 q를 치면 어떻게 될까?
regex를 이용해서 수정해보자.
if (guessedNumText.matches("-?\\d{1,2}")) {
마이너스까지 허용한 코드
Do while loop
차이점은 While 구문이 뒤로 간다는 것이다.
=> guarantee the statement at least runs one time.
import java.util.Random;
public class GuessIt3 {
public static void main(String[] args) {
int randomNum = new Random().nextInt(10) + 1;
String guessedNumText = null;
do {
guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
if (guessedNumText.matches("-?\\d{1,2}")) {
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
System.out.printf("The random number was %d. You got it!%n", randomNum);
return;
} else {
System.out.printf("You didn't got it%n", randomNum);
}
}
} while (!"q".equals(guessedNumText));
}
}
단순 교체한 코드
keep track how many guesses user did 를 구현해보자.
int wrongGuessCount = 1;
do {
guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
if (guessedNumText.matches("-?\\d{1,2}")) {
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
System.out.printf("The random number was %d. You got it in %d of tries!%n", randomNum, wrongGuessCount);
return;
ternary operator를 사용해보자.
if (guessedNum ==randomNum ){
String tryText = wrongGuessCount == 1 ? "try" : "tries";
System.out.printf("The random number was %d. You got it in %d of tries!%n", randomNum, wrongGuessCount);
return;
삼중연산자를 사용해 1이라면 단수, 아니라면(그 이상) 복수를 사용하도록 구현해주었다.
한편, loop문 안에서 사용된 변수는 loop가 끝나고 나면 garbage collcted로 분류된다.
메모리 사용에 있어서 변수를 가까이 붙이는 것의 유용성
user가 영원히 guess하지 않고 적당한 수준에서 멈출 수 있도록 하는 기능을 구현해보자.
q를 누르거나 wrongcount가 5이상이면 종료하도록 하는 코드를 구현해보자.
while (!"q".equals(guessedNumText) && wrongGuessCount < 5);
if hit q => "q".equals(guessedNumText) => true
5 미만이면 wrongGuessCount => 역시 true
여기서 논리연산자는 both have to be true=> true 리턴
} while (!"q".equals(guessedNumText) && wrongGuessCount < MAX_ALLOWED_TRIED);
// q 누르면 = 1 , wrong guess 5 미만 = 1 => loop continues
// q 누르면 = 1 , wrong guess 5 이상 = 0 => loop stops
// q 안누르면 = 0 , wrong guess 5 미만 = 1 => loop stops
// q 안누르면 = 0 , wrong guess 5 이상 = 0 => loop stops
Constant로 만든 방법
Overall
import java.util.Random;
public class GuessIt3 {
public static final int MAX_ALLOWED_TRIED = 4;
public static void main(String[] args) {
int randomNum = new Random().nextInt(10) + 1;
String guessedNumText = null;
int wrongGuessCount = 1;
do {
guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
if (guessedNumText.matches("-?\\d{1,2}")) {
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
String tryText = wrongGuessCount == 1 ? "try" : "tries";
System.out.printf("The random number was %d. You got it in %d of %s!%n", randomNum, wrongGuessCount, tryText);
return;
} else {
System.out.printf("You didn't got it%n", randomNum);
wrongGuessCount ++;
}
}
} while (!"q".equals(guessedNumText) && wrongGuessCount <= MAX_ALLOWED_TRIED);
// q 누르면 = 1 , wrong guess 5 미만 = 1 => loop continues
// q 누르면 = 1 , wrong guess 5 이상 = 0 => loop stops
// q 안누르면 = 0 , wrong guess 5 미만 = 1 => loop stops
// q 안누르면 = 0 , wrong guess 5 이상 = 0 => loop stops
if (wrongGuessCount >= MAX_ALLOWED_TRIED){
System.out.printf("you've had %d incorrect guesses. The random number is %d. Ending.%n", wrongGuessCount-1, randomNum);
return;
}
}
}
for 반복문
위의 do 문을 바꿔보자.
public static void main(String[] args) {
int randomNum = new Random().nextInt(10) + 1;
String guessedNumText = null;
int wrongGuessCount = 1;
for (; wrongGuessCount <=MAX_ALLOWED_TRIED; wrongGuessCount++) {
guessedNumText = System.console().readLine("Please guess a number btw 1 and 10 inclusively: ");
if (guessedNumText.matches("-?\\d{1,2}")) {
int guessedNum = Integer.parseInt(guessedNumText);
if (guessedNum ==randomNum ){
String tryText = wrongGuessCount == 1 ? "try" : "tries";
System.out.printf("The random number was %d. You got it in %d of %s!%n", randomNum, wrongGuessCount, tryText);
return;
} else {
System.out.printf("You didn't got it%n", randomNum);
}
}
}
if (wrongGuessCount >= MAX_ALLOWED_TRIED){
System.out.printf("you've had %d incorrect guesses. The random number is %d. Ending.%n", wrongGuessCount-1, randomNum);
return;
}
}
continue의 역할
go back to the top of the loop
I don't want to stop the loop rather just print out different message.
루프를 죽이지 않으면서 ending particular iteration.
for loop의 기본 형식
public class ForLoopExample {
public static void main(String[] args) {
int counter;
for (counter = 0; counter < 10; counter++) {
System.out.printf("Counter is %d%n", counter);
}
}
}
무한 루프 = loop doesn't know where to stop.
public class ForLoopExample {
public static void main(String[] args) {
int counter;
for (counter = 0; ; counter++) {
System.out.printf("Counter is %d%n", counter);
}
}
}
일반적으로 리스트를 돌면서 추출하는 방식
public class ForLoopExample {
public static void main(String[] args) {
String[] fruits = {"apple", "orange", "pear", "plum"};
for (int counter =0; counter<fruits.length; counter++){
System.out.printf("The current fruit is %s%n", fruits[counter]);
}
}
}
The current fruit is apple
The current fruit is orange
The current fruit is pear
The current fruit is plum
Enhanced for loop을 알아보자.
public class ForLoopExample {
public static void main(String[] args) {
String[] fruits = {"apple", "orange", "pear", "plum"};
for (String fruit: fruits){
System.out.printf("The current fruit s %s%n", fruit);
}
}
}
The current fruit s apple
The current fruit s orange
The current fruit s pear
The current fruit s plum
따라서 counter가 굳이 필요하지 않고 array에서 요소를 추출할 때는
enhanced를 쓰면 깔끔하다.