java工具類(三)之生成若干位隨機數
java 生成若干位隨機數的問題
在一次程式設計的過程中偶然碰到一個小問題,就是需要生成一個4位數的隨機數,如果是一個不到4位大的數字,前面可以加0來顯示。因為要求最後是一個4位的整數,不帶小數點。當時就想到了幾個辦法:
一、 用Math.random()
當時就這麼想到,Math.random()方法不正好可以生成[0, 1)之間的數字麼?如果用這個數字乘以10000不就是一個從[0, 1000)之間的數字了麼? 於是當時就想到了這麼一段程式碼:
for(int i = 0; i < 10; i++) { double number = Math.random(); System.out.println(number * 10000); }
為了看看顯示結果的情況,用了一個迴圈。
結果顯示的執行結果如下:
372.4564939910557
3645.150576934125
6102.8559042871575
9953.00445315209
2063.1098637100063
6217.048150847877
5069.372886881975
8076.738641253838
1288.394893502075
14.324909511606032
很明顯,在最初的設想中,有幾個地方是沒有考慮到的。
1. Math.random()生成的隨機數不一定只有小數點後4位的。所以後面還是可能有多位,所以顯示出來的結果有多個小樹點。有人可能會想,如果我再把結果中的小數部分去掉呢?這並沒有解決問題,其實也就是第二個問題。
2. 因為生成的數字可能足夠小,哪怕乘了10000後還是個2位數字或者3位數字。這樣的話,如果要湊成一個整4位的,還需要手工在前面補0.
那麼,如果我們用這種很笨的辦法來做的話,該怎麼樣呢?首先需要乘10000,然後將小數部分去掉,再判斷生成的數字,1位的補3個0,2位的補2個0,3位的補1個0.
3. 還有一個問題就是,如果我們要將這個問題擴大到生成n位的隨機數時,總不能後面去判斷多少位,然後再去補0吧。而且,數字足夠大的時候還可能會產生溢位的問題,int不夠用了,估計還要用BigInteger。
看來,這個辦法不是很好。實現起來也挺費勁。就為了實現這麼點功能,還費這老鼻子勁,不值得。
二、逐位生成隨機數
這個辦法相對來說就會簡單一點。我們如果利用生成整數的隨機函式,然後一位一位的去生成的話。可能會簡單一點。於是我們可以用一個這樣的辦法:
Random rnd = new Random();
public String getRandomNumber(int digCount) {
StringBuilder sb = new StringBuilder(digCount);
for(int i=0; i < digCount; i++)
sb.append((char)('0' + rnd.nextInt(10)));
return sb.toString();
}
我們用到了java.util.Random這個類。nextInt(n)這個方法可以返回一個從0到n的隨機數。
通過這個辦法,我們可以生成一個若干位的隨機數,然後用一個字串的方式來表示。當數字足夠長的時候,也不用擔心會溢位。
補充:
前面的生成隨機數方法還存在著一個小的缺陷。在隨機數生成的方法中,我們需要每次重複呼叫的時候生成的數字都是不一樣的。這樣就需要每次隨機化的時候提供一個隨機化的種子(seed)。比較常用的方式就是採用當前的時間。所以說一個比較完整的利用當前時間作為種子,再將需要隨機化的範圍指定的步驟才算是一個完整的過程。具體的程式碼如下:
import java.util.Random;
import java.util.Date;
class RandomizeNumber
{
public static void testDate()
{
Date date = new Date();
long timeMill = date.getTime();
System.out.println(timeMill);
Random rand = new Random(timeMill);
for(int i = 0; i < 20; i++)
{
System.out.println(rand.nextInt(50));
}
}
public static void main(String[] args)
{
testDate();
}
}
如果我們每次執行這段程式碼,就會發現結果不一樣,這樣就可以保證足夠隨機化了。