본문 바로가기
Programming/Java, Spring

[Java 기초문법] | Control flow | loop, while 반복문, do while 반복문, for 반복문, enhanced for loop

by Renechoi 2022. 10. 18.

[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를 쓰면 깔끔하다. 

 

 

 

반응형