[Java ] 개념노트 42 Random 클래스 이해하기

[Java 개념노트 42] Random 클래스 이해하기

안녕하세요. Java 개념노트 시리즈 마흔두 번째 글입니다.

지난 글에서는 최댓값, 최솟값, 절댓값, 반올림, 제곱, 랜덤 실수 등을 제공하는 Math 클래스에 대해 정리했습니다. 이번 글에서는 랜덤 숫자를 더 다양한 방식으로 생성할 수 있는 Random 클래스에 대해 알아보겠습니다.

프로그램을 만들다 보면 주사위, 로또 번호, 랜덤 인증번호, 게임 아이템 확률, 무작위 문제 출제처럼 랜덤 값이 필요한 경우가 많습니다. 자바에서는 이런 랜덤 값을 만들 때 Math.random()뿐만 아니라 Random 클래스를 사용할 수 있습니다.


1. Random 클래스란?

Random 클래스는 정수, 실수, boolean 값 등을 무작위로 생성할 수 있게 해주는 클래스입니다.

Math.random()은 0.0 이상 1.0 미만의 실수만 반환하지만, Random 클래스는 정수, 실수, 참/거짓 값을 더 편하게 만들 수 있습니다.

쉽게 말하면
Random 클래스는 다양한 랜덤 값을 만들기 위한 자바의 랜덤 생성 도구입니다.

2. Random 클래스 import하기

Random 클래스는 java.util 패키지에 있습니다. 따라서 사용하려면 import가 필요합니다.

import java.util.Random;

전체 구조는 다음과 같습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int number = random.nextInt();

        System.out.println(number);
    }
}

Math 클래스는 import 없이 사용할 수 있었지만, Random 클래스는 java.util.Random을 import해야 합니다.

3. Random 객체 만들기

Random 클래스는 객체를 생성해서 사용합니다.

Random random = new Random();

이렇게 만든 random 객체를 사용해서 랜덤 정수, 랜덤 실수, 랜덤 boolean 값을 만들 수 있습니다.

핵심 포인트
Randomnew Random()으로 객체를 만든 뒤, 그 객체의 메서드를 호출해서 랜덤 값을 생성합니다.

4. nextInt() 랜덤 정수 만들기

nextInt()는 랜덤 정수를 생성합니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int number = random.nextInt();

        System.out.println(number);
    }
}

실행할 때마다 다른 정수가 나올 수 있습니다.

-152384923
83472812
204938475

결과는 예시입니다. nextInt()는 양수와 음수를 포함한 넓은 범위의 정수를 반환할 수 있습니다.

5. nextInt(범위) 사용하기

원하는 범위 안에서 랜덤 정수를 만들고 싶다면 nextInt(숫자)를 사용합니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int number = random.nextInt(10);

        System.out.println(number);
    }
}

random.nextInt(10)0부터 9까지의 정수 중 하나를 반환합니다.

가능한 값: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

주의
nextInt(10)은 10을 포함하지 않습니다. 항상 0 이상 10 미만의 정수를 반환합니다.

6. 1부터 10까지 랜덤 정수 만들기

nextInt(10)은 0부터 9까지 나오므로, 1부터 10까지 만들고 싶다면 마지막에 1을 더하면 됩니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int number = random.nextInt(10) + 1;

        System.out.println(number);
    }
}

가능한 값은 다음과 같습니다.

가능한 값: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

흐름을 정리하면 다음과 같습니다.

random.nextInt(10)      → 0부터 9까지
random.nextInt(10) + 1  → 1부터 10까지

7. 원하는 범위의 랜덤 정수 공식

시작값과 끝값이 정해진 랜덤 정수를 만들 때는 다음 공식을 사용할 수 있습니다.

int number = random.nextInt(끝값 - 시작값 + 1) + 시작값;

예를 들어 5부터 10까지 랜덤 정수를 만들고 싶다면 다음과 같이 작성합니다.

Random random = new Random();

int number = random.nextInt(10 - 5 + 1) + 5;

System.out.println(number);

정리하면 다음과 같습니다.

끝값: 10
시작값: 5
개수: 10 - 5 + 1 = 6

random.nextInt(6)  → 0부터 5까지
+ 5                → 5부터 10까지

8. 주사위 만들기

주사위는 1부터 6까지의 숫자 중 하나가 나와야 합니다. Random 클래스로 간단히 만들 수 있습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int dice = random.nextInt(6) + 1;

        System.out.println("주사위 결과: " + dice);
    }
}

실행 결과는 매번 달라질 수 있습니다.

주사위 결과: 4

9. 로또 번호 맛보기

로또 번호처럼 1부터 45까지의 숫자 중 하나를 만들 수도 있습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int lottoNumber = random.nextInt(45) + 1;

        System.out.println("로또 번호: " + lottoNumber);
    }
}

가능한 값은 1부터 45까지입니다.

가능한 값: 1 ~ 45

단, 실제 로또처럼 중복 없는 6개 번호를 만들려면 배열, 반복문, 중복 검사 또는 컬렉션을 함께 사용해야 합니다. 이 글에서는 Random 클래스 사용법에 집중하겠습니다.

10. nextDouble() 랜덤 실수 만들기

nextDouble()은 0.0 이상 1.0 미만의 랜덤 실수를 반환합니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        double number = random.nextDouble();

        System.out.println(number);
    }
}

실행할 때마다 결과는 달라질 수 있습니다.

0.38472918

nextDouble()의 결과 범위는 0.0 <= 값 < 1.0입니다.

11. nextBoolean() 랜덤 true/false 만들기

nextBoolean()은 랜덤으로 true 또는 false를 반환합니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        boolean result = random.nextBoolean();

        System.out.println(result);
    }
}

실행 결과는 다음 중 하나입니다.

true
false

동전 앞면과 뒷면처럼 두 가지 결과 중 하나를 랜덤으로 고를 때 사용할 수 있습니다.

12. 랜덤 동전 던지기 예제

nextBoolean()을 사용해서 동전 던지기를 만들어보겠습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        boolean front = random.nextBoolean();

        if (front) {
            System.out.println("앞면");
        } else {
            System.out.println("뒷면");
        }
    }
}

실행할 때마다 앞면 또는 뒷면이 나올 수 있습니다.

앞면

13. nextLong(), nextFloat() 맛보기

Random 클래스는 정수와 double 외에도 여러 타입의 랜덤 값을 만들 수 있습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        long longNumber = random.nextLong();
        float floatNumber = random.nextFloat();

        System.out.println(longNumber);
        System.out.println(floatNumber);
    }
}

nextLong()은 랜덤 long 값을 반환하고, nextFloat()은 0.0 이상 1.0 미만의 float 값을 반환합니다.

14. Random과 Math.random() 비교

Random 클래스와 Math.random()은 모두 랜덤 값을 만들 수 있습니다. 하지만 사용 방식과 편의성이 조금 다릅니다.

구분 Math.random() Random 클래스
사용 방식 Math.random() new Random() 후 메서드 호출
반환 기본값 double int, double, boolean 등 다양함
정수 범위 생성 계산식 필요 nextInt(범위)로 편리함
seed 설정 직접 사용하기 어려움 seed 지정 가능

간단히 랜덤 실수 하나만 필요하면 Math.random()도 충분합니다. 하지만 랜덤 정수나 다양한 타입의 랜덤 값이 필요하면 Random 클래스가 편리합니다.

15. seed란?

Random 클래스는 seed 값을 지정할 수 있습니다. seed는 랜덤 값 생성의 시작 기준이 되는 값입니다.

같은 seed를 사용하면 같은 순서의 랜덤 값이 나옵니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random1 = new Random(1);
        Random random2 = new Random(1);

        System.out.println(random1.nextInt(100));
        System.out.println(random1.nextInt(100));

        System.out.println(random2.nextInt(100));
        System.out.println(random2.nextInt(100));
    }
}

실행 결과는 다음과 같이 같은 순서로 나올 수 있습니다.

85
88
85
88

random1random2가 같은 seed를 사용했기 때문에 같은 순서의 랜덤 값이 생성됩니다.

기억하기
seed를 같게 주면 랜덤 값의 흐름을 재현할 수 있습니다. 테스트할 때 같은 결과를 반복해서 확인하고 싶을 때 도움이 됩니다.

16. 같은 Random 객체를 재사용하기

랜덤 값을 여러 번 만들 때는 Random 객체를 한 번 만들고 계속 재사용하는 것이 좋습니다.

권장하는 방식

Random random = new Random();

int a = random.nextInt(10);
int b = random.nextInt(10);
int c = random.nextInt(10);

불필요하게 반복 생성하는 방식

int a = new Random().nextInt(10);
int b = new Random().nextInt(10);
int c = new Random().nextInt(10);

두 번째 방식도 동작은 할 수 있지만, 매번 객체를 새로 만들기 때문에 불필요합니다. 보통은 Random random = new Random();을 한 번 작성하고 재사용합니다.

17. 랜덤 인증번호 만들기

0부터 9까지 숫자를 조합해서 간단한 6자리 인증번호를 만들 수 있습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        StringBuilder code = new StringBuilder();

        for (int i = 0; i < 6; i++) {
            int number = random.nextInt(10);
            code.append(number);
        }

        System.out.println("인증번호: " + code);
    }
}

실행 결과는 매번 달라질 수 있습니다.

인증번호: 482901

0부터 9까지의 숫자를 6번 생성해서 문자열로 이어 붙였습니다.

18. 랜덤 배열 값 뽑기

배열과 Random을 함께 사용하면 배열 안의 값 중 하나를 랜덤으로 선택할 수 있습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        String[] menus = {"김밥", "라면", "돈가스", "비빔밥"};

        Random random = new Random();

        int index = random.nextInt(menus.length);

        System.out.println("오늘의 메뉴: " + menus[index]);
    }
}

실행 결과는 매번 달라질 수 있습니다.

오늘의 메뉴: 돈가스

menus.length를 범위로 사용했기 때문에 배열 인덱스 범위를 벗어나지 않습니다.

19. nextInt(0)은 오류가 난다

nextInt(범위)에서 범위 값은 반드시 1 이상이어야 합니다.

Random random = new Random();

int number = random.nextInt(0); // 오류 발생

nextInt(0)은 가능한 숫자 개수가 0개라는 뜻이므로 사용할 수 없습니다.

주의
nextInt(숫자)에서 숫자는 반드시 양수여야 합니다. 0이나 음수를 넣으면 오류가 발생합니다.

20. Random 클래스 주요 메서드 정리

자주 사용하는 Random 클래스 메서드를 정리하면 다음과 같습니다.

메서드 역할 예시
nextInt() 랜덤 정수 생성 random.nextInt()
nextInt(int bound) 0 이상 bound 미만의 랜덤 정수 생성 random.nextInt(10)
nextDouble() 0.0 이상 1.0 미만의 double 생성 random.nextDouble()
nextFloat() 0.0 이상 1.0 미만의 float 생성 random.nextFloat()
nextLong() 랜덤 long 값 생성 random.nextLong()
nextBoolean() 랜덤 true 또는 false 생성 random.nextBoolean()

21. Random 클래스 전체 예제

이번에는 Random 클래스의 여러 기능을 함께 사용하는 예제를 보겠습니다.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int dice = random.nextInt(6) + 1;
        int lotto = random.nextInt(45) + 1;
        double rate = random.nextDouble();
        boolean coin = random.nextBoolean();

        System.out.println("주사위: " + dice);
        System.out.println("로또 번호 하나: " + lotto);
        System.out.println("랜덤 실수: " + rate);

        if (coin) {
            System.out.println("동전: 앞면");
        } else {
            System.out.println("동전: 뒷면");
        }
    }
}

실행 결과는 다음과 비슷합니다.

주사위: 2
로또 번호 하나: 37
랜덤 실수: 0.68291
동전: 앞면

랜덤 값은 실행할 때마다 달라질 수 있습니다.

22. Random 클래스 사용 시 자주 하는 실수

Random 클래스를 처음 사용할 때는 아래와 같은 실수를 자주 합니다.

실수 문제점 해결 방법
import java.util.Random; 누락 Random 클래스를 찾지 못함 파일 위에 import 작성
nextInt(10)이 1부터 10까지라고 착각 실제로는 0부터 9까지 nextInt(10) + 1 사용
끝값 포함 여부 착각 bound 값은 포함되지 않음 0 이상 bound 미만으로 기억
nextInt(0) 사용 범위가 0이라 오류 발생 bound는 반드시 양수로 설정
Random 객체를 계속 새로 생성 불필요하게 객체를 반복 생성 Random 객체를 한 번 만들고 재사용

23. 직접 연습해보기

아래 코드를 직접 작성하고 실행해보세요.

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();

        int dice = random.nextInt(6) + 1;
        System.out.println("주사위 결과: " + dice);

        int score = random.nextInt(101);
        System.out.println("랜덤 점수: " + score);

        String[] prizes = {"커피", "쿠폰", "포인트", "꽝"};
        int index = random.nextInt(prizes.length);
        System.out.println("당첨 결과: " + prizes[index]);

        StringBuilder authCode = new StringBuilder();

        for (int i = 0; i < 6; i++) {
            authCode.append(random.nextInt(10));
        }

        System.out.println("인증번호: " + authCode);
    }
}

실행 결과는 다음과 비슷합니다.

주사위 결과: 5
랜덤 점수: 82
당첨 결과: 포인트
인증번호: 730481

모든 랜덤 결과는 실행할 때마다 달라질 수 있습니다.

24. 이번 글 정리

이번 글에서는 랜덤 값을 만들 때 사용하는 Random 클래스에 대해 정리했습니다. 핵심 내용은 다음과 같습니다.

  • Random 클래스는 다양한 랜덤 값을 생성하는 클래스이다.
  • Randomjava.util 패키지에 있으므로 import가 필요하다.
  • Random random = new Random();으로 객체를 생성한다.
  • nextInt()는 랜덤 정수를 생성한다.
  • nextInt(10)은 0부터 9까지의 정수를 반환한다.
  • 1부터 10까지 만들려면 random.nextInt(10) + 1을 사용한다.
  • 원하는 범위 공식은 random.nextInt(끝값 - 시작값 + 1) + 시작값이다.
  • nextDouble()은 0.0 이상 1.0 미만의 double 값을 반환한다.
  • nextBoolean()은 true 또는 false를 랜덤으로 반환한다.
  • 같은 seed를 사용하면 같은 순서의 랜덤 값이 나올 수 있다.
  • 랜덤 값을 여러 번 만들 때는 Random 객체를 한 번 만들고 재사용하는 것이 좋다.

한 줄 요약
Random 클래스는 정수, 실수, boolean 등 다양한 랜덤 값을 만들 수 있게 해주는 자바의 랜덤 생성 클래스입니다.

다음 글 예고
다음 글에서는 [Java 개념노트 43] 날짜와 시간 API 이해하기라는 주제로 LocalDate, LocalTime, LocalDateTime을 사용해 날짜와 시간을 다루는 방법을 정리해보겠습니다.

GWDEVELBlog Java 개념노트 시리즈