隨機數是任何一種編程語言最基本的特征之一,在技術開發中應用很廣泛,因為有時我們需要隨機生成一個固定長度的數字、字符串亦或者是需要隨機生成一個不定長度的數字、或者進行一個模擬的隨機選擇等。Java就為我們提供了最基本的工具,可以幫助開發者生成不同條件下需要的隨機數。java中產生隨機數和c的差不多,一般有兩種隨機數,一個是Math中random()方法,一個是Random類。不過不管是c還是java,要產生隨機數都需要設置隨機數種子,如果設置的是一樣的話,每次獲得的隨機數是一樣的。下面來匯總一下常見的不同類型的java隨機數是如何生成的。
(數據類型)(最小值+Math.random()*(最大值-最小值+1))
例1:從1到10的int型隨數
(int)(1+Math.random()*(10-1+1))
例2:
隨機生成0~100中的其中一個數
在上面我們已經知道了Math.random()返回的只是從0到1之間的小數,如果要50到100,就先放大50倍,即0到50之間,這里還是小數,如果要整數,就強制轉換int,然后再加上50即為50~100。
最終代碼:
(int)(Math.random()*50) + 50
Random random = new Random();//默認構造方法
Random random = new Random(1000);//指定種子數字
在進行隨機時,隨機算法的起源數字稱為種子數(seed),在種子數的基礎上進行一定的變換,從而產生需要的隨機數字。
相同種子數的Random對象,相同次數生成的隨機數字是完全相同的。也就是說,兩個種子數相同的Random對象,第一次生成的隨機數字完全相同,第二次生成的隨機數字也完全相同。
例:獲取[0, 100)之間的int整數。
int i2 = random.nextInt(100);
Random 的函數接口:
// 構造函數(一): 創建一個新的隨機數生成器。
Random()
// 構造函數(二): 使用單個 long 種子創建一個新隨機數生成器: public Random(long seed) { setSeed(seed); } next 方法使用它來保存隨機數生成器的狀態。
Random(long seed)
boolean nextBoolean() // 返回下一個“boolean類型”偽隨機數。
void nextBytes(byte[] buf) // 生成隨機字節并將其置于字節數組buf中。
double nextDouble() // 返回一個“[0.0, 1.0) 之間的double類型”的隨機數。
float nextFloat() // 返回一個“[0.0, 1.0) 之間的float類型”的隨機數。
int nextInt() // 返回下一個“int類型”隨機數。
int nextInt(int n) // 返回一個“[0, n) 之間的int類型”的隨機數。
long nextLong() // 返回下一個“long類型”隨機數。
synchronized double nextGaussian() // 返回下一個“double類型”的隨機數,它是呈高斯(“正常地”)分布的 double 值,其平均值是 0.0,標準偏差是 1.0。
synchronized void setSeed(long seed) // 使用單個 long 種子設置此隨機數生成器的種子。
Random類中的常用方法:
Random 類中的方法比較簡單,每個方法的功能也很容易理解。需要說明的是,Random類中各方法生成的隨機數字都是均勻分布的,也就是說區間內部的數字生成的幾率是均等的。下面對這些方法做一下基本的介紹:
a 、public boolean nextBoolean()
該方法的作用是生成一個隨機的boolean值,生成true和false的值幾率相等,也就是都是50%的幾率。
b 、public double nextDouble()
該方法的作用是生成一個隨機的double值,數值介于[0,1.0)之間,這里中括號代表包含區間端點,小括號代表不包含區間端點,也就是0到1之間的隨機小數,包含0而不包含1.0。
c 、public int nextInt()
該方法的作用是生成一個隨機的int值,該值介于int的區間,也就是-2的31次方到2的31次方-1之間。
如果需要生成指定區間的int值,則需要進行一定的數學變換,具體可以參看下面的使用示例中的代碼。
d 、public int nextInt(int n)
該方法的作用是生成一個隨機的int值,該值介于[0,n)的區間,也就是0到n之間的隨機int值,包含0而不包含n。
如果想生成指定區間的int值,也需要進行一定的數學變換,具體可以參看下面的使用示例中的代碼。
e 、public void setSeed(long seed)
該方法的作用是重新設置Random對象中的種子數。設置完種子數以后的Random對象和相同種子數使用new關鍵字創建出的Random對象相同。
直接使用nextDouble方法獲得。
b、生成[0,5.0)區間的小數
double d2 = r.nextDouble() * 5;
因為nextDouble方法生成的數字區間是[0,1.0),將該區間擴大5倍即是要求的區間。
同理,生成[0,d)區間的隨機小數,d為任意正的小數,則只需要將nextDouble方法的返回值乘以d即可。
c、生成[1,2.5)區間的小數 [n1,n2]
double d3 = r.nextDouble() * 1.5 + 1;【也就是 r.nextDouble() * (n2-n1)+n1】
生成[1,2.5)區間的隨機小數,則只需要首先生成[0,1.5)區間的隨機數字,然后將生成的隨機數區間加1即可。
同理,生成任意非從0開始的小數區間[d1,d2)范圍的隨機數字(其中d1不等于0),則只需要首先生成[0,d2-d1)區間的隨機數字,然后將生成的隨機數字區間加上d1即可。
d、生成任意整數
int n1 = r.nextInt();
直接使用nextInt方法即可。
e、生成[0,10)區間的整數
int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);
以上兩行代碼均可生成[0,10)區間的整數。
第一種實現使用Random類中的nextInt(int n)方法直接實現。
第二種實現中,首先調用nextInt()方法生成一個任意的int數字,該數字和10取余以后生成的數字區間為(-10,10),因為按照數學上的規定余數的絕對值小于除數,然后再對該區間求絕對值,則得到的區間就是[0,10)了。
同理,生成任意[0,n)區間的隨機整數,都可以使用如下代碼:
int n2 = r.nextInt(n);
n2 = Math.abs(r.nextInt() % n);
f、生成[0,10]區間的整數
int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);
相對于整數區間,[0,10]區間和[0,11)區間等價,所以即生成[0,11)區間的整數。
g、生成[-3,15)區間的整數
int n4 = r.nextInt(18) - 3; 【也就是 r.nextInt() * (n2-n1)+n1】 n1是個負數
n4 = Math.abs(r.nextInt() % 18) - 3;
生成非從0開始區間的隨機整數,可以參看上面非從0開始的小數區間實現原理的說明。
方法三:通過System.currentTimeMillis()來獲取一個當前時間毫秒數的long型數字。
通過System.currentTimeMillis()來獲取隨機數。實際上是獲取當前時間毫秒數,它是long類型。使用方法如下:
final long l = System.currentTimeMillis();
final long l = System.currentTimeMillis();
final int i = (int)( l % 100 );
下面通過示例演示上面3種獲取隨機數的使用方法。 源碼如下(RandomTest.java):
import java.util.Random;
import java.lang.Math;
/**
* java 的隨機數測試程序。共3種獲取隨機數的方法:
* (01)、通過System.currentTimeMillis()來獲取一個當前時間毫秒數的long型數字。
* (02)、通過Math.random()返回一個0到1之間的double值。
* (03)、通過Random類來產生一個隨機數,這個是專業的Random工具類,功能強大。
*
* @author skywang
* @email kuiwu-wang@163.com
*/
public class RandomTest{
public static void main(String args[]){
// 通過System的currentTimeMillis()返回隨機數
testSystemTimeMillis();
// 通過Math的random()返回隨機數
testMathRandom();
// 新建“種子為1000”的Random對象,并通過該種子去測試Random的API
testRandomAPIs(new Random(1000), " 1st Random(1000)");
testRandomAPIs(new Random(1000), " 2nd Random(1000)");
// 新建“默認種子”的Random對象,并通過該種子去測試Random的API
testRandomAPIs(new Random(), " 1st Random()");
testRandomAPIs(new Random(), " 2nd Random()");
}
/**
* 返回隨機數-01:測試System的currentTimeMillis()
*/
private static void testSystemTimeMillis() {
// 通過
final long l = System.currentTimeMillis();
// 通過l獲取一個[0, 100)之間的整數
final int i = (int)( l % 100 );
System.out.printf("\n---- System.currentTimeMillis() ----\n l=%s i=%s\n", l, i);
}
/**
* 返回隨機數-02:測試Math的random()
*/
private static void testMathRandom() {
// 通過Math的random()函數返回一個double類型隨機數,范圍[0.0, 1.0)
final double d = Math.random();
// 通過d獲取一個[0, 100)之間的整數
final int i = (int)(d*100);
System.out.printf("\n---- Math.random() ----\n d=%s i=%s\n", d, i);
}
/**
* 返回隨機數-03:測試Random的API
*/
←上一篇: 完整的java數組操作應用知識匯總