static Random rnd = new Random();
static int random(int n) {
return Math.abs(rnd.nextInt()) % n;
}
- Random이 사용하는 난수 생성기인 LCG의 특징
public static void main(String[] args){
int n = 2 * (Integer.MAX_VALUE / 3);
int low = 0;
for (int i = 0; i < 1000000; i++)
if (random(n) < n/2)
low++;
System.out.println(low);
}
- random 메서드가 정상적으로 동작한다면 약 50만개가 출력되야 하지만, 실제로 돌려보면 666,666에 가까운 값을 얻는다.
- 무작위로 생성된 수 중에서 2/3이 중간값보다 낮은 쪽으로 쏠린 것이다.
nextInt()가 Integer.MIN_VALUE를 반환하면 Math.abs도 Integer.MIN_VALUE를 반환한다.
- n이 2의 제곱수가 아닌 경우 %는 음수를 반환한다.
- Integer.MIN_VALUE의 절대값이 정수 범위를 초과하기 때문이다.
public int nextInt(int bound) {
if (bound <= 0) {
throw new IllegalArgumentException(BAD_BOUND);
}
int r = next(31);
int m = bound - 1;
if ((bound & m) == 0)
r = (int)((bound * (long)r) >> 31);
else {
for (int u = r;
u - (r = u % bound) + m < 0;
u = next(31))
;
}
return r;
}
- 자바 7부터는 Random을 더 이상 사용하지 않는 것이 좋다.
- Random보다 고품질의 무작위 수를 생성하고 속도도 더 빠르다.
- 그 코드를 작성한 전문가의 지식과 앞서 사용한 다른 프로그래머들의 경험을 활용할 수 있다.
- 핵심적인 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 된다.
- 따로 노력하지 않아도 성능이 지속해서 개선된다.
- 기능이 점점 많아진다.
- 다른 개발자들이 더 읽기 쉽고, 유지보수하기 좋고, 재활용하기 쉬운 코드가 된다.
- java.lang, java.util, java.io와 그 하위 패키지
- 컬렉션 프레임워크와 스트림 라이브러리
- java.util.concurrent의 동시성 기능
- 바퀴를 다시 발명하지 말자.
- 나만의 특별한 기능이 아니라면 이미 누군가 구현해놓았을 가능성이 크다.