자바 랜덤함수 | 자바 입문강좌 19

자바 랜덤함수

자바 랜덤함수(Java Random Function)의 사용법을 알아보겠습니다.

1강부터 19강까지의 내용을 학습했다면 이제는 자바의 API를 하나씩 알아갈 차례입니다. 자바는 모든 라이브러리가 클래스로 만들어져 있습니다.

자바 랜덤함수
자바 랜덤함수

java.lang.Math 클래스

Math 클래스는 java.lang 패키지에 포함됩니다. java.lang 패키지는 모든 클래스의 상위 클래스인 java.lang.Object부터 자바 프로그래밍의 기본이 되는 각종 클래스들을 포함합니다.

import 문을 딱히 명시해도 않아도 java.lang 패키지는 import 되있습니다.

Math 클래스에는 이름처럼 수학에 관련한 static 메소드들이 있습니다.

의사 난수를 생성하는 random함수는 static 으로 인스턴스 없이 사용할 수 있습니다. 반환값은 double 형 0.0~1.0 의 범위에서 생성한 난수입니다.

public class Main {
    public static void main(String[] args) {
        double myRand = Math.random();

        for (int i = 0; i < 3; i++) {
            System.out.println(i + ": " +myRand);
            myRand = Math.random();
        }
            System.out.println("finally : " + myRand);
    }
}
[실행값]
0: 0.778098473452544
1: 0.20028682836479783
2: 0.6995866111503665
finally : 0.946285960565024

소수점을 버리고 정수 범위를 지정하기 위해서는 아래와 같은 표현식을 사용합니다.

    public static void main(String[] args) {
        int myRand = 0;
        for (int i = 0; i < 3; i++) {
            myRand = (int)(Math.random()*10)+1;
            System.out.println(i + ": " +myRand);
        }
    }
[실행값]
0: 3
1: 7
2: 10

다른 언어의 랜덤함수 라이브러리에 비해 다소 번거롭긴 합니다만 메소드를 정의해서 사용해도 됩니다. 랜덤(시작수, 범위) 같은 형태로 함수를 만들 수 있습니다.

아래는 랜덤(1, 10) 함수로 1부터 시작해서 10까지 범위의 난수를 출력합니다.

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            showMyRandom(5,15);
        }
    }
    public static void showMyRandom(int min, int range){
        int myRand = 0;
        System.out.println((int)(Math.random()*range)+min);
    }
}
[실행값]
10
12
5

java.util.Random 클래스

이쪽은 java.lang.Math 보다 난수생성에 향상된 Random 클래스입니다. 인스턴스를 생성하여 쓰는 부분이 차이가 있습니다. Math 클래스 처럼 의사 난수 발생기입니다.

난수의 결과를 정수형 int, float, boolean 형 등 다양한 자료형으로 리턴할 수 있습니다.

다음은 32비트 정수형 난수를 생성하는 코드입니다.

import java.util.Random;

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

        System.out.println();
        System.out.println("[default seed]");
        for (int i = 0; i < 3; i++) {
            System.out.println(myRand.nextInt());
        }
        System.out.println();
        System.out.println("[new seed]");
        Random newSeed = new Random(System.currentTimeMillis());
        for (int i = 0; i < 3; i++) {
            System.out.println(newSeed.nextInt());
        }
    }
}
[실행값]

[default seed]
-629688980
13898585
588425857

[new seed]
1960814606
-44811205
-284862123

Random 클래스 생성시 시드(seed)를 받습니다. seed를 받는 이유는 컴퓨터에서는 완전한 자연계의 난수를 생성할 수 없기 때문에 ‘의사난수’ – 그럴 듯한 난수 – 를 만들어서 써야하기 때문입니다.

난수의 품질은 예측 불가능성입니다. 만약 난수의 알고리즘을 추적할 수 있는 수식이 있다면 누군가 난수를 악용할 소지가 있죠.

난수 공식이 아무리 좋아도 누군가 풀어버릴 수 있다는 한계가 있기 때문에 보통 현재시간을 시드로 사용합니다. System.currentTimeMillis는 1000분의 1초의 에픽타임을(1970년1월1일부터 현재까지 흐른 시간) 반환하므로 하나의 장치를 더 주는 것입니다.

즉 랜덤함수 자체의 의사난수 알고리즘 + 시드(seed)를 부여함으로써 예측을 더 어렵게 만드는 것입니다. 풀수 없다고는 하지 않았지만 일반적인 프로그램의 난수로 사용하는데 큰 문제가 없습니다.

컴퓨터에서 의사난수(Pseudo-random numbers)를 사용하는 건 자연계의 난수를 만들기 위해서는 정교한 물리적 장치가 필요하기 때문이라는 아이디어는 한번 생각해 볼 가치가 있습니다.

주사위를 던지는 것이라고 생각해 보면 좋습니다. 주사위를 던지는 대신 알고리즘을 적용하는 것 입니다. 수식이 매우 복잡하다고 하는데요. 수학에 자신있는 분들은 한번 도전해 보셔도 좋을 겁니다.

위의 코드에서 범위를 지정하려면 nextInt 에 인수로 범위(bound)를 전달합니다. (0부터9까지 난수생성)

 nextInt(10)

ThreadLocalRandom 클래스

java.util.concurrent.ThreadRandom 은 스레드 별로 독립적인 랜덤 클래스입니다. 아무래도 스레드가 각자 격리된 상태에서 사용하면 Random 클래스 보다 고품질의 난수가 생성될 것을 기대할 수 있습니다. (JDK 7)

static 메소드 current 로 인스턴스 없이 사용가능합니다.

import java.util.concurrent.ThreadLocalRandom;

public class Main {
    public static void main(String[] args) {
        int myRand1 = ThreadLocalRandom.current().nextInt(100);
        int myRand2 = ThreadLocalRandom.current().nextInt(100);

        System.out.println("I: " + myRand1);
        System.out.println("I: " + myRand2);

        double myRand3 = ThreadLocalRandom.current().nextDouble(100.0);
        double myRand4 = ThreadLocalRandom.current().nextDouble(100.0);

        System.out.println("D: " + myRand3);
        System.out.println("D: " + myRand4);
    }
}

이 외에도 Random 클래스가 개발되고 있습니다만, 입문 단계에서는 이정도를 알아두고 필요할 때는 JDK 문서를 검색하시길 바랍니다.

요약

랜덤한 수를 생성할 수 있기 때문에 프로그래밍이 더욱 흥미진진해집니다. 거의 대부분의 프로그래밍 언어에서 난수 생성기를 기본 라이브러리에 포함시키는데 난수생성기는 어떤 프로그램을 작성하는데도 사용할 수 있습니다.

자바의 기본 클래스만 하더라도 매우 방대하기 때문에 모두 외우는 것은 불가능합니다. API는 인터넷상에 공개되어 있으니 필요할 때 문서를 읽고 사용할 수 있는 능력을 습득하는게 필요합니다.

Random 클래스에는 이외에도 다양한 메소드와 멤버변수가 있으니 외부참조문서의 java 홈페이지를 방문해보시기 바랍니다.

외부참조문서

java.lang (Java Platform SE 7 ) (oracle.com)

Math (Java Platform SE 8 ) (oracle.com)

Random (Java Platform SE 8 ) (oracle.com)

자바 Random 클래스로 무작위 문자열 만들기 | Random Class

Leave a Comment